The Inquisitive Coder - Davy Brion’s Blog

Trying to walk that thin line between intelligence and ignorance

Archive for March, 2008

Thread-safe repositories

Posted by Davy Brion on 25th March 2008

First of all, this is not about true DDD repositories… i just needed an in-memory data container with basic storing/retrieving functionality so i figured i’d call it a Repository.

These repositories will be accessed by multiple concurrent threads so i needed to make sure that all access to the underlying dictionary is properly synchronized. But, i also want them to be highly usable and i especially wanted a thread-safe way of dynamically executing queries on them.

Here’s what i came up with:

    public class Repository<T> where T : Member

    {

        private readonly object _monitor = new object();

        private readonly Dictionary<Id, T> _members = new Dictionary<Id,T>();

 

        protected object Monitor

        {

            get { return _monitor; }

        }

 

        /// <summary>

        /// any derived classes that use this property are responsible for their own locking!

        /// (use the Monitor property for that)

        /// </summary>

        protected Dictionary<Id, T> Members

        {

            get { return _members; }

        }

 

        public virtual void Store(T member)

        {

            lock (Monitor)

            {

                Put(member);

            }

        }

 

        public virtual void StoreRange(IEnumerable<T> members)

        {

            lock (Monitor)

            {

                foreach (T member in members)

                {

                    Put(member);

                }

            }

        }

 

        public virtual void Remove(T member)

        {

            lock (Monitor)

            {

                if (Members.ContainsValue(member))

                {

                    Members.Remove(member.Id);

                }

            }

        }

 

        public virtual T Get(Id id)

        {

            lock (Monitor)

            {

                if (!Members.ContainsKey(id))

                {

                    return null;

                }

 

                return Members[id];

            }

        }

 

        public virtual T FindFirst(Func<T, bool> expression)

        {

            lock (Monitor)

            {

                return Members.Values.FirstOrDefault(expression);

            }

        }

 

        public virtual IEnumerable<T> FindAll(Func<T, bool> expression)

        {

            lock (Monitor)

            {

                return Members.Values.Where(expression).ExecuteImmediately();

            }

        }

 

        /// <summary>

        /// this method should ONLY be called when a lock on Monitor has been acquired!

        /// </summary>

        /// <param name=”member”></param>

        private void Put(T member)

        {

            // this overwrites existing entries with the same ID… it’s not a mistake ;)

            Members[member.Id] = member;

        }

    }

each access to the dictionary is properly synchronized (at least, i think so… if anyone knows of a better way to do the locking, please leave a comment) and i can still execute dynamic queries on them by passing lambda expressions to the FindFirst and FindAll methods, like this:

            User me = userReposority.FindFirst(u => u.FirstName == “Davy” && u.LastName == “Brion”);

            IEnumerable<User> usersWithNoLastName =

                userReposority.FindAll(u => string.IsNullOrEmpty(u.LastName));

Share/Save/Bookmark

Posted in Multithreading, Software Development | 2 Comments »

got memory?

Posted by Davy Brion on 25th March 2008

build notification memory usage

this is for the Build Notification power tool for TFS 2008. 34 megs of RAM… for a little system tray icon that notifies you when a build has started/stopped. And it’s only watching 3 builds. 34 megs of RAM. Unbelievable…

Share/Save/Bookmark

Posted in Off Topic | No Comments »

why oh why does visual studio create multiple .vsmdi files?

Posted by Davy Brion on 20th March 2008

I’m forced to use MSTest at work… i had to use it at a previous client, hated it then and i still hate it now (even though the 2008 version is a lot faster than the 2005 version).

One of the things that bugs me the most is the .vsmdi file it creates, or better yet, the fact that it keeps creating vsmdi files even though i already have one! I’m sure anyone who’s ever worked with MSTest has experienced this issue.

I’d be very grateful to hear answers to the following questions:

1) Why can’t it simply use the already existing .vsmdi file?
2) Why oh why has this problem been there ever since the 2005 version was released?
3) Why can’t they fix this? i can’t imagine this being a hard bug to fix… and i definitely can’t imagine needing more than 3 years to fix this
4) Is there anyone within Microsoft who’s actually used this crap?
5) Why should i use MSTest over the NUnit/TestDriven.NET combo? Obviously, Microsoft can’t even get the integration with its own product right.

Oh and before you ask, you can even get this problem without using source control or read-only files, so please don’t suggest that might be the reason :)

Share/Save/Bookmark

Tags:
Posted in Rants | No Comments »

Another use for extension methods

Posted by Davy Brion on 18th March 2008

i’m not a huge fan of extension methods, allthough they certainly can be useful at times. I’m using lambda expressions on collections that can be accessed by concurrent threads, and as you may or may not know, lambda expressions usually aren’t executed until you iterate over the results. But my collections need to be locked while the expression is executed, so i really need to make sure they are executed immediately (before my lock is released). An easy way to do it is to just use the .ToList() method on the resulting IEnumerable. But that really looks weird because it really doesn’t show the intent of what you’re trying to do.

So I defined the following extension method:

    public static class Extensions

    {

        public static IEnumerable<T> ExecuteImmediately<T>(this IEnumerable<T> enumerable)

        {

            // in case of an IEnumerable<T> that is the result of a lambda expression, the

            // expression might not have executed yet (deferred execution). In this application

            // we’ll be executing a lot of lambda expressions on collections that need to

            // be synchronized, so we need to make sure those lambda expressions are executed

            // immediately, while the lock on the parent collection is maintained.

            // Simply returning a .ToList() of the enumerable will make sure that the lambda

            // expression is executed immediately and the result is valid.

            // Should the creation of a new List<T> prove to be too expensive, we only need to

            // modify the line below to use a faster approach and the entire application would

            // benefit from it

            return enumerable.ToList();

        }

    }

and now i can do this:

            lock (_parentsLock)

            {

                return _parents.Where(p => String.IsNullOrEmpty(p.Path)).ExecuteImmediately();

            }

Which clearly shows the intent of what is being done.

Share/Save/Bookmark

Posted in Software Development | No Comments »

Encapsulating collections

Posted by Davy Brion on 17th March 2008

When i have classes that need to expose collections, i always try to make sure that consumers only get a read-only version of that collection. Consumers should be able to easily use those collections, but if something would need to be added or removed from a collection, it should happen with a specific call to the owner of that collection instead of manipulating the collection directly. In .NET 2.0 i often used the ReadOnlyCollection class for this, but now with .NET 3.5 there is a much easier way. By simply exposing the collections as IEnumerable you prevent consumers from directly adding or removing items from your collection, but with the LINQ extension methods, they are still very usable to anyone that need to use them.

Small example:

    public class Member

    {

        private readonly List<Member> _parents;

        private readonly List<Member> _children;

 

        public Member()

        {

            _parents = new List<Member>();

            _children = new List<Member>();

        }

 

        public IEnumerable<Member> Children

        {

            get { return _children; }

        }

 

        public IEnumerable<Member> Parents

        {

            get { return _parents; }

        }

 

        public void AddChild(Member child)

        {

            _children.Add(child);

        }

 

        public void RemoveChild(Member child)

        {

            _children.Remove(child);

        }

 

        public void AddParent(Member parent)

        {

            _parents.Add(parent);

        }

 

        public void RemoveParent(Member parent)

        {

            _parents.Remove(parent);

        }

    }

the Parents and Children collections are completely encapsulated, yet still highly usable to consumers:

usableencapsulatedcollection.png

Share/Save/Bookmark

Posted in Software Development | No Comments »

What is ALT.NET?

Posted by Davy Brion on 14th March 2008

As you know, i try to minimize the posts that are merely links to other interesting content, but this is a must-read.

If you’re interested in more, be sure to subscribe to the altdotnet mailinglist. More info can also be found here.

Share/Save/Bookmark

Tags:
Posted in Software Development | No Comments »

A picture says a 1000 words

Posted by Davy Brion on 11th March 2008

Noma’s First Run

i’m finally spending some time on Noma again, and this is a screenshot of the results of trying it out for the first time.

Share/Save/Bookmark

Posted in Uncategorized | No Comments »