Justin a.k.a. The Code Monkey

Code Monkey [kohd muhng'-kee] n : 1. Creature known for it's ability to transform caffeine into code. 2. Justin Jones
posts - 10 , comments - 26 , trackbacks - 0

Variations on a Repository Pattern: Part I

Ok, Let’s try this again.

<ObligatoryIShouldBlogMoreSection Skip='DontCareJustShowMeTheCode'>

Way back when I decided to blog more often because, well, mainly someone told me I should. That didn’t work out, but I still like Scott Hanselman’s idea as a blog as a place to keep cool code ideas. Well, he says that’s why he started the blog anyway. As an aside, he also says you should maintain your own site and own your own content. I’m working on that, and already have a cool domain name picked out. While I scrap together the funds to put that together, I’ll continue to blog here in the meantime.

A little history and my plans going forward.

So for various personal reasons my life has been filled with personal drama for about three years or so now. This had the unfortunate effect of distracting me from keeping up with A) this blog and B) my skills. In IT terms that amount of time is a small eternity. Entire programing paradigms rise and fall in that amount of time. How software is made can completely change. JavaScript is cool now. Web Forms are not cool now. MVC is cool. .NET seems to be on it’s way out. JQuery is a requirement. So I find myself with my skills a bit stagnated and the monumental task ahead of me of making up for lost time. To look at it positively, this gives me a lot of blog fodder. I’ve resurrected an old pet project (that I actually use a fair bit on my own network) and begun the process of over-engineering the hell out of it so that I can play with some new technologies. It is, of course, interspersed with a lot of old standby technologies that I still love and feel are still relevant. As I’m making progress on it, my plan going forward is to take different areas that I’m working on and blog about them here. Mostly so that I can refer back to the patterns easily. If you get something out of it too, bonus for you. Winking smile Ok, enough meta-blogging, back to the code.

</ObligatoryIShouldBlogMoreSection>

 

I’m a fan of CSLA, so of course I wrote the guts of this in CSLA. I’ve recently returned to web work, and for various reasons proposed using CSLA as the basis of a website rewrite. In fairness, the web is not always where CSLA shines, at least not in Web Forms, but it gives you a solid middle tier to work with. The problem, though, is it’s hard to unit test CSLA objects. The framework’s focus on mobile objects makes heavy use of the factory pattern, which makes dependency injection problematic at best. The solution I came up with was heavily based on code examples by Rocky Lhotka himself on one way of handling this problem.

So I started with an assembly which defines some basic interfaces for abstracting away the data layer. The idea here is that I can inject a mock data layer during unit testing so that I can test the objects without a database. I placed this in a framework assembly and posted it as a NuGet package in my own feed (more on that later). Bear in mind that this is a work in progress.

I start with a static class called DalFactory

    public static class DalFactory
    {
        public static Type DalType { get; set; }

        public static IDalManager ManagerInstance { get; set; }

        public static IDalManager GetManager()
        {
            if(ManagerInstance == null)
            {
                if(DalType==null)
                {
                    var dalTypeName=ConfigurationManager.AppSettings["DalManagerType"];
                    if(!string.IsNullOrEmpty(dalTypeName))
                        DalType=Type.GetType(dalTypeName);
                    else
                        throw new NullReferenceException("No DalManagerType specified.");
                    if(DalType==null)
                        throw new ArgumentException(string.Format("Type {0} could not be found",dalTypeName));
                }
                ManagerInstance= (IDalManager)Activator.CreateInstance(DalType);
            }
            return ManagerInstance;
        }
    }

Don’t h8 on my spacing conventions. I started out in C++.

Concurrency issues aside, what this does is allow me to specify the type of manager to return in the configuration file, or by passing in a Type or an actual instance to the factory. The instance will override the type or the configuration. To reset the factory, pass in an instance or null to the instance.

What did that get me? At unit test time I can create a mock of type IDalManager and pass it directly into ManagerInstance, giving me a type of dependency injection. At runtime I can specify the actual type in the configuration file and keep the code ignorant of the actual data implementation.

IDalManager looks like this:

    public interface IDalManager: IUnitOfWork
    {
        T GetProvider<T>() where T : class, IDal;
    }

The Unit Of Work idea was an afterthought, but it solved some logistical issues, mainly the ability to support transactions. I called it IUnitOfWork, but it’s not a strict implementation of the pattern, more of a variation on the pattern. IUnitOfWork looks like this:

public interface IUnitOfWork : IDisposable
{
    void Commit();
    void Rollback();
    event EventHandler Committed;
    event EventHandler RolledBack;
}

 

If you’re familiar with the pattern, you’ll see some things missing. The main thing I was after here was the ability to transact the entire process. The events at the bottom were another logistical addition, because child objects needed to subscribe to the transaction but wouldn’t get an updated Id until the entire thing was committed. The event allows them to come back afterwards and get the Id from the DTO they were working with.

At this point the code can call DalManager.GetProvider<> and get what effectively is an interface to a particular entity type’s repository. You’ll notice the IDal restriction on GetProvider. IDal has nothing defined in it, it’s simply to make sure that the return type is restricted to an implementation of IDal. IDal is the parent of IDal<T,K> which is what we really want to return here.

    public interface IDal<T,K> : IDal
    {
        IEnumerable<T> Retrieve();
        T Retrieve(K key);
        bool Exists(K key);
        void Insert(T item);
        void Update(T item);
        void Delete(K key);
    }

 

T is the type of entity we’re working with, K is the type of the key. I’m having a discussion with another developer over how appropriate it is to define the key type here, so I may change direction on this, but for now it works.

This is a good starting point. Next we need an actual implementation specific to the entities that exist in the project. This is rather involved in and of itself, so I’ll save that for the next post.

Comments and criticisms are welcome. This is basically what I came up with to solve a particular issue. If you have another idea, please post it in the comments.

Print | posted on Sunday, March 24, 2013 2:06 AM | Filed Under [ .Net 4.0 Visual Studio 2010 Unit Testing CSLA Repository Data Access ]

Feedback

Gravatar

# re: Variations on a Repository Pattern: Part I

Having used CSLA, I know that factories are a common pattern to use, by why not just use a IoC container to inject your IDalManager instance into the objects themselves? If you're going through the extra effort exposing the setters solely for testing purposes, it creates confusion. Also you have to be aware of what you're doing because if ManagerInstance is called before GetManager() is called you run into an issue.
3/26/2013 9:38 PM | Steve Evans
Gravatar

# re: Variations on a Repository Pattern: Part I

As I'm discovering, you're absolutely right. The instance property is problematic because the manager needs to be disposed. I haven't solved this one yet. The problem with a pure IoC approach is that CSLA object creation is controlled by the DataPortal, so I can't just pass it into the constructor. I can't hold on to the manager instance past the data portal methods because the objects are mobile. The beauty of CSLA is also one of it's major drawbacks, it's hard to unit test. What I'm after is exactly that, an approach that makes CSLA objects unit testable. I suppose I'm trying to have my cake and eat it too. The point to the ManagerInstance was so that I could pass a mock in and have complete control within the unit test, completely isolating it from any actual database implementation. I have quite a bit of CSLA experience, but I'm relatively inexperienced with mocking and IoC containers, so if you have any ideas along these lines I'd love to hear them. The implementation I have so far is a variation of an example by Rocky. As I said, it's a work in progress. I'm blogging it as I figure it out.
4/1/2013 11:42 PM | Justin
Post A Comment
Title:
Name:
Email:
Comment:
Verification:
 
 

Powered by: