Monday, December 22, 2008

Using Dependency Injection with CSLA.NET

In this post, I'm going to talk about one way to implement Dependency Injection with CSLA.NET
NOTE: My discussions and code samples are using CSLA.NET 3.5.

Background

CSLA.NET.  I'm a big fan.  I have been even back before it went .NET in the VB5 and VB6 days.
I don't know actual statistics, but I would wager that CSLA.NET is probably the most popular framework for creating object-oriented business objects in .NET.  If you're building even a moderately complex line-of-business application where you want your business logic to live in one place (instead of spread all over the place, the worst being in your UI), you want a middle tier that takes advantage of object-oriented design (not just a set of classes that mimic the structure of the database), and optionally have everything just work in a distributed environment, then you should definitely take a close look at CSLA.NET.
I'm also a big fan of automated tests around my business layer.  And when I say tests, I'm referring to unit tests, where I want to validate just the behavior of my business object and nothing else.  In other words, I'm not interested in testing the other layers that my business object may interact with (like the database or a logging component).  Those would be integration or regression tests.  Those are good too, by the way, but unit tests should come first.
Since business objects almost always have to communicate with other layers, your unit tests need the ability to fake those layers out in order to test your business logic in isolation.  There are variety of ways to do this, but a popular one is to abstract calls to these layers using Dependency Injection and then use a mocking framework to inject a fake version of that layer.  To really do Dependency Injection, you need to use a framework of some kind (typically called an IOC Container) to handle your dependency instances and automatically perform injections on your objects.

Problem

So, like I said, I really love the CSLA.NET framework.  But with all of its awesome excellence, I've always been challenged writing true unit tests against business objects that use it.  This is because CSLA.NET makes it difficult to implement Dependency Injection.  Why?  In short: CSLA.NET creates your business object instances for you.  This happens in the servers-side portion of the DataPortal.  Dependency Injection works best if it can have some kind of access to the object creation process so an object's dependencies can be injected.  Unfortunately, the DataPortal does not provide any sort of hook where you can create your object.  The DataPortal does this all behind the scenes as a black box and then gives you your object instance after creation, letting you then execute your data-access code in the DataPortal_* methods.
To be fair, the latest version of CSLA.NET, 3.6 which just released, does give you access into the creation of your business objects via the new object factory feature.  However, there are two challenges with going down this road:
  1. You end up having to write a lot more than just object creation into your object factory classes since the object factory is also responsible for performing all data access including the state population of your business objects. 
  2. You have to write a factory class for every business object that requires dependency injection.  Couple this with the first point, and that adds up to a lot more coding just so you can have control over the creation of your business objects.
There is also another challenge, and that is that the creation of objects on the server-side of the DataPortal isn't the only place business objects in CSLA.NET are being created!  One of the great features of CSLA.NET is this idea of mobile objects: your business objects have the ability to be transported from one physical tier to another.  However, every time an object goes mobile it needs to be serialized.  When it gets to the destination tier, it needs to be deserialized and deserialization involves recreating the object instance except this time its done within the bowels of the .NET Framework.  Yuck!  Even more difficult to hook into.  And by the way, as of CSLA.NET 3.5, for consistency this serialization/deserialization process even occurs when everything happens in-process on one physical tier.

Solution

The solution I finally stumbled upon essentially gave up on the idea of trying to hijack the object creation process either in the DataPortal or worse yet in the .NET Framework itself during deserialization. 
The good news is that most IOC Container frameworks out there allow you to perform dependency inject with an existing object instance.  In my case, I'm using Unity, the IOC Container from Microsoft, which is a member of their Application Blocks family.  Unity's container object has a method called BuildUp that let's you do exactly this.
And the other piece of good news is that CSLA.NET allows very easy access to an object instance just after it is created either by the server-side DataPortal or by deserialization.  All you have to do is override a couple virtual methods and you're done!

Implementation

My implementation of this was to create a set of base classes that all inherit from main CSLA.NET base classes that do the necessary overrides and perform the dependency injection.  Let's build the base class for BusinessBase<T>, probably the most used CSLA.NET base class.
First, let's get the basics out of the way.  We'll declare an abstract class called InjectableBusinessBase<T> that inherits from BusinessBase<T> and contains a protected constructor, which all abstract classes should have:
[Serializable]
public abstract class InjectableBusinessBase<T>
    : BusinessBase<T>
    where T : BusinessBase<T>
{

    protected InjectableBusinessBase() { }

}
Now, let's add the necessary overrides to hook into post-object creation so we can kick off our dependency injection:
    protected override void DataPortal_OnDataPortalInvoke(DataPortalEventArgs e)
    {
        Inject();
        base.DataPortal_OnDataPortalInvoke(e);
    }

    protected override void Child_OnDataPortalInvoke(DataPortalEventArgs e)
    {
        Inject();
        base.Child_OnDataPortalInvoke(e);
    }

    protected override void OnDeserialized(StreamingContext context)
    {
        Inject();
        base.OnDeserialized(context);
    }
First we overrode DataPortal_OnDataPortalInvoke.  This gets called by the server-side DataPortal when a root level business object is created.  Then we overrode Child_OnDataPortalInvoke which gets called by the server-side DataPortal whenever a child object is created by the DataPortal (a new feature as of CSLA.NET 3.5 that I highly recommend).  Finally, we overrode OnDeserialized, which, through the help of BusinessBase<T>, gets called by the deserialization process of .NET.
In all three cases, we're calling an Inject method, which is a private method declared in our base class.  It looks like this:
    private void Inject()
    {
        var type = this.GetType();
        Ioc.Container.BuildUp(type, this);
    }
Nothing too fancy here.  We're essentially calling the Unity BuildUp method which requires the type of our business object and the business object instance itself.
What is a little exotic, if you're familiar with Unity, is the Ioc.Container code.  Our base class needs some way to access the Unity container instance against which to call BuildUp.  I've created a utility class called Ioc that has a static Container property that returns this.  I'll include the code for this class as well as all the code for the various base classes at the end of this post.  For now, just know that the code Ioc.Container returns our IOC container.
That pretty much is all that's required to make dependency injection  work with CLSA.NET and Unity!  However, I do have one more method I want to include in my base class:
    protected TDependency EnsureDependency<TDependency>(TDependency dependency) 
        where TDependency : class
    {
        if (dependency == null)
            throw new MissingDependencyInjectionException(this.GetType(), typeof(TDependency));
        return dependency;
    }
The purpose of this method will become a little more clear when we take a look at an example concrete business object class that inherits from InjectableBusinessBase<T>.  Essentially all this method does is return the same object that gets passed in.  However, before it returns it, the method checks to make sure the object is null; if so, it throws a custom exception that basically says a required dependency instance is missing that it's of a certain type and is contained within the object of this type.  I'll include the source code for this exception class at the end of the post as well.

Sample Concrete Class

To make all this gel, let's code up a concrete business object class that inherits from our base class.  I'm going to code up a very simple Customer class that has two properties, ID and Name, and a single Fetch factory method.  Here's the code so far:
[Serializable]
public sealed class Customer
    : InjectableBusinessBase<Customer>
{

    private static PropertyInfo<int> IdProperty = 
        RegisterProperty<int>(new PropertyInfo<int>("Id"));
    public int Id
    {
        get { return GetProperty<int>(IdProperty); }
    }

    private static PropertyInfo<string> NameProperty = 
        RegisterProperty<string>(new PropertyInfo<string>("Name"));
    public string Name
    {
        get { return GetProperty<string>(NameProperty); }
        set { SetProperty<string>(NameProperty, value); }
    }

    private Customer() { }

    public static Customer Fetch(int id)
    {
        var criteria = new SingleCriteria<Customer, int>(id);
        return DataPortal.Fetch<Customer>(criteria);
    }
    
}
Nothing new here other than the class inherits from InjectableBusinessBase<Customer>.  We have two properties declared using the new CSLA.NET 3.5 managed property syntax.  Then we have the standard private constructor and the static factory method which uses the DataPortal to create and fetch our business object from the database.
Now I want to introduce a dependency into my class that performs the actual data access necessary to fetch the customer, which will be performed in a standard DataPortal_Fetch method.  This data access object will implement a custom interface called ICustomerDataAccess and will have a method called FetchData that takes a customer ID and returns a DTO that contains my customer data.  Here's what my ICustomerDataAccess interface might look like:
public interface ICustomerDataAccess
{
    ICustomerDto FetchData(int id);
}
By the way, a DTO (data transfer object) is just an object that contains nothing but data.  For mocking purposes, my DTO is an interface (called ICustomerDto). 
In an upcoming post, I'll show a more elegant way to abstract away the data access layer in CSLA.NET using dependency injection and the Repository pattern.
Let's add a field to my class that will contain this dependency:
    [NonSerialized]
    [NotUndoable]
    private ICustomerDataAccess _dataAccess;
Notice that I've added two attributes to this field.  The first, NonSerializedAttribute, is important because we don't want this dependency (or probably any dependency) to be serialized if the business object were to become mobile and transferred from one physical tier to another.  In the case of data access, it really only needs to occur on the tier that performs data access (i.e. an application server).
The second attribute, NotUndoableAttribute, comes from the CSLA.NET framework.  It tells CSLA.NET that this field is not to participate in the undo functionality provided by the BusinessBase<T> class.  This is because the dependency does not contain any business object state that would need to be rolled back if the users were to perform an Undo.
Having both of these attributes in place essentially relieves us of the need to make our dependency serializable.  The actual implementation class of ICustomerDataAccess can be just a plain old object.
Now we need a way to inject this dependency into our business object.  Unity gives you three ways: constructor, set-able property, or method.  We can't use the Customer constructor since we're performing the dependency injection after the instance has been created by the DataPortal or deserialization.  We could use the set-able property.  However, I personally like the method approach since, if you have multiple dependencies, you can inject all of them in a single call. 
We just have one in our example, so here's the code:
    [InjectionMethod]
    public void Inject(ICustomerDataAccess dataAccess)
    {
        if (dataAccess == null)
            throw new ArgumentNullException("dataAccess");
        _dataAccess = dataAccess;
    }
My method can be named anything, but it needs to be decorated with the special Unity InjectionMethodAttribute and it needs a parameter for each of my dependencies so I can set the fields.  Notice I also throw an ArgumentNullException if whatever is doing the injection passes in a null.  We want to fail if this ever happens.
Finally, we need to add the DataPortal_Fetch method that will use our data access dependency:
    private void DataPortal_Fetch(SingleCriteria<Customer, int> criteria)
    {
        var customerData = EnsureDependency(_dataAccess).FetchData(criteria.Value);
        LoadProperty<int>(IdProperty, customerData.Id);
        LoadProperty<string>(NameProperty, customerData.Name);
    }
The first thing we do is call the FetchData method of my ICustomerDataAccess object to obtain the customer DTO.  Here is where you can see the EnsureDependency method in action that we coded earlier in the base class.  If we wrap the _dataAccess dependency in a call to EnsureDependency, we know we're not going to get a NullReferenceException, which is non-descriptive and hard to debug.  Rather we'll get a more descriptive exception that explains exactly what dependency is missing from what object.
Once we have the DTO, we can simply populate our business object in the standard CSLA.NET 3.5 way.

Conclusion

There you have it!  Dependency Injection and CSLA.NET living peacefully side-by-side. 
If you'd like to take a look at the complete set of source code for this, which includes all the Injectable* base classes, the MissingDependencyInjectionException class, the Ioc helper class, and the sample Customer business object code, you can download it hereBefore the sample code will compile, you will also need to download CSLA.NET 3.5 and Unity 1.2 and update the assembly references accordingly.

UPDATE: The download link is actually now to the larger sample code set that demonstrates the Repository pattern (see these two blog posts for more details).  To see the DI-specific code discussed in the above blog post, check out the CslaRepositoryTest.Core namespace.

Now I'm not pretending that this is the only way to make this work.  If there are other people out there who've made Dependency Injection and CSLA.NET work better, perhaps with a different IOC Container like StructureMap or Castle Windsor, write a comment and let me know!

20 comments:

cusTom3 said...

had to go and bring back memories of all the days i wasted trying to use csla.net and dependency injection didn't ya :P

for what it's worth, i do still like some of the ideas present in csla.net, but with the leaps and bounds being made in .net 3 and 3.5 i have completely moved away from even recommending it as an architectural option.

i much prefer using an orm like nhibernate or entity framework and using linq.

Pete said...

I feel for you, man. But you might be interested in taking another look at CSLA.NET, especially the versions from 3.5 on. Those advances in .NET have also propelled CSLA.NET. Not to mention CSLA.NET for Silverlight (3.6).

And regarding NHybernate and EF, would you consider those good choices for building a business layer? I know they work great as a data access layer. In the same way, CSLA.NET isn't a data access layer framework or an ORM - it's specifically focused around the business logic of your application.

Speaking of business layers and data access layers, I'm about to post another entry on how to use the Repository pattern with CSLA.NET, which allows you to abstract your data access layer, whatever it may be, completely, so you can take advantage of the dependency injection and testability I demonstrated in this post.

Good luck!
~pete

Rad said...

Pete,

When can we expect your blog entry
on Repository pattern with CSLA.NET? I suppose it will be used along with DI/Unity? Does it have dependency on Enterprise Library 4.1?
I would like to create CSLA Codesmith templates using this approach. I am still learning the whole TDD and MDD and it would be nice if
you could provide some demo. Could you use ProjectTracker sample and incorporate your ideas?
If you already have such examples could you please send them at radoslavATcenturytelDOTnet.

Thanks,
Rad

Pete said...

The blog post is coming soon. Hopefully by next week.

To answer your other questions:
- Yes it will use DI/Unity. It will be based on the approach I used in this post.
- It won't be dependent on EL4.1 other than using Unity, which can be used with or without EL.
- I will have code samples, but they probably won't be with Project Tracker, although that's a good idea. For the initial post, I'll probably use something simpler, for demonstration. However, it would be interesting to attempt to convert PT over to use Repository. It would take a little effort, but would be very cool.

~pete

Broomeister said...

Great post, thanks Pete! You must have developed a sibling project to test drive the project, I'd be interested to see that along with the configuration file(s). I've downloaded the source and have read through it but I'm scratching my head a bit over how to actually use it.

Pete said...

Broomeister, yes, such a project does exist. I'm working on another post that uses the dependency injection technique I explain in this post to implement the Repository Pattern with CSLA.NET. That post will include a full VS2008 solution that demonstrates everything. Stay tuned...

~pete

mamboer said...

Hi,On applying repository pattern using Nhibernate in CSLA.NET ,look at this project
http://code.google.com/p/cslarepo/

dagda1 said...

CSLA.NET is the antithesis of POCO

mendicant said...

This post has just cured me from ever wanting to try CSLA.Net.

Thanks!

Pete said...

My pleasure. What will you be using instead?

~pete

Sean said...

Hi Pete,

I know you've dealt with this in upcoming posts. However, it'd be great, for closure, if you could provide a unity.config with the sample in this post? It clarifies where exactly the injection is called from.

Thanks,
Sean

Anonymous said...

Hello,

I understand that this comment is nearly a year after your original post, I just wanted to point out that at least EditableRootListBase and NameValueListBase also require overriding of event handlers in order to use this injection technique consistently across all CSLA DataPortal access.

Dale Thompson said...

I forgot to mention, that it might be better to also use the CSLA DataMapper to do the copiues between the DTOs and the main business objects as well.

John Varan said...

We have a huge enterprise web app that is using CSLA.NET, and this article will come in very handy for unit testing. Thanks for writing it!

Code Connection Blog

Anonymous said...

Please can someone explain why the dependencies have to be injected via an inject method, can the business object not just request them from the container when it needs them during the dataportal_fetch etc??

Pete said...

Because that wouldn't be dependency injection - that's service locator. The ultimate goal of DI is to build classes (in this case CSLA business objects) that don't need to know anything about the container. They simply get their dependencies injected in by the container.

Anonymous said...

Thanks for that explanation Pete,

The reason I raised that question, is because I am struggling with a couple of things as I am implementing this pattern, and I would really appreciate any input or guidance you could give me to help put me back on track with this.. It may even help others who stumble upon the same chain of thought as I.
It is not uncommon to have a child list item object - such as CustomerInfo, and that object have a helper method to help navigate to another object - i.e "GetCustomer" - which would return a customer object - (ICustomer)

However in order for the GetCustomer() method to return a customer it must have an instance of the appropriate ICustomerFactory object. My immediate thought was that this basically means that each child "CustomerInfo" object must have the "ICustomerFactory" "injected" into it.. However It then struck me that If you have a list with 1000 customerInfo's in, it would be quite a performance hit, to have injection performed on every item just on the odd chance that a few of those items might actually have that method called and then require the ICustomerFactory object instance to return an I
ICustomer.

My last question - along the same lines as the first, in your sample application, the "repository" is injected on every child so that the child can create its necessary dto's when doing updates / inserts / deletes etc. That does mean a lot of injection however, and if you have large list objects, again - especially if only one or 2 of those items actually get modified and need to do any data access. My question is, as the parent passes a "context" to each child, why would it not be better to pass the repository as well? In that scenario each child could create its dto's using that same repository and you no longer need to have the repository injected into each child objecy instance seperately..

I do not have much experience with DI or IoC - I am new to the idea, any guidance you could share would be most welcome. Are my concerns valid?

Kind Regards

Darrell

James Posey said...

Hi Pete,

I know this post is several years old, but I'm working with CSLA 4.1 and the latest unity framework version from ENtLib 5.0. I'm having trouble getting the businessobject to instatiate when It's registered with the Unity ontainer. Error Message: Resolution of the dependency failed, type = "AA.Pension.Business.Administration.TableCode.TableCode", name = "(none)".

I not sure if it's the version of Rhino Mocs I'm using or what? I followed the example code to the letter and even made the needed changes to the injectable classes you provided to get it to work under .net 4.5. Any suggestion would be great. I can also send the code if need be.

Thanks,

James

Peter Stromquist said...

James,

Just about everything about this post (which is over four years old now) has changed, including my involvement in some of the more recent versions of CSLA.NET. I even noticed that the download link is no longer working (again).

I think what I'm going to take the sample code as-is (working against all the original versions of Unity and CSLA.NET) and create a new repo in my little corner of GitHub. That way at least you can see how it used to work. From there myself (or anyone who wants to fork and submit a pull request) can make enhancements and maybe even create a branch or two showing how DI can work with more modern versions of CSLA.NET and Unity.

And as a side note: personally, I've shifted over to preferring Autofac over Unity for an IOC container library.

~pete

Peter Stromquist said...

There... I got ambitious and just pushed the code up to GitHub:

https://github.com/twistedstream/CslaRepositoryTest

I updated the post itself so the download link points to it as well.