A few months ago I made the switch from CastleWindsor to StructureMap for my dependency injection needs. It’s a more active project, more up to date with the times, more extensible, and definitely has a better interface for configuring through code rather than xml. After a few growing pains I’ve grown to like it a lot ( I’m using version 2.5). However in the last few days I’ve run into a roadblock it seems, and it all has to do with the lifecycle/scope of objects.

A lot of dependency objects in the typical application could be singletons if designed right (covers head from flames). However there is a point at which that ceases to be the case, that’s where unit of work patterns come into play. A unit of work has only a finite lifespan and should then be disposed. In keeping with good testability and design patterns you will probably also want to have a ready made unit of work object injected into the classes that need them. Every time that you ask for a unit of work you should be supplied with a fresh new copy. That’s where configuring the lifecycles properly in your DI tool should come into play.

As code is a common language, I will code out what I am talking about as simply as possible.

//Think of this as a data session
public class Session
{
}
 
public class Model1
{
    public Session Session { get; set; }
 
    public Model1(Session session)
    {
        Session = session;
    }
}
 
public class Model2
{
    public Session Session { get; set; }
 
    public Model2(Session session)
    {
        Session = session;
    }
}
 
//this is my shell, it needs some models
public class Shell
{
    public Model1 Model1 { get; set; }
    public Model2 Model2 { get; set; }
 
    public Shell(Model1 model1, Model2 model2)
    {
        Model1 = model1;
        Model2 = model2;
    }
}

This is a pretty straight forward scenario. We have a shell (entry point) that contains a couple of models, each of these models requires a unique data session so that it can pull and work with its data independently.

Let’s use StructureMap to wire these together so that we just create our shell and have its dependencies filled for us automatically. Remember that by default StructureMap does not create singletons, so using the default config should result in transient, per-request objects.

ObjectFactory.Initialize(
    x => {
             x.BuildInstancesOf()
                 .TheDefaultIsConcreteType();
             x.BuildInstancesOf()
                 .TheDefaultIsConcreteType();
             x.BuildInstancesOf()
                 .TheDefaultIsConcreteType();
             x.BuildInstancesOf()
                 .TheDefaultIsConcreteType();
    });

Now let’s test to make sure that we have a unique data session.

Shell shell = ObjectFactory.GetInstance();
 
Assert.AreNotEqual(shell.Model1.Session, shell.Model2.Session);

And this is where we come to the fail part. The data session contained in each model is identical, the same as if we had declared it as a singleton. We know that the configuration is right because doing it this way works.

Assert.AreNotEqual(ObjectFactory.GetInstance(), ObjectFactory.GetInstance());

Why this happens has been a matter of great curiosity to me, and even though I’m not a great StructureMap expert I’ll hazard an educated guess. Each time that you make a declarative request for the root of an object graph, StructureMap creates a unique BuildSession. Inside that build session there is a cache of instantiated objects. The session then builds one object for each dependency in the graph no matter how many times it is requested in that graph. The objects may be built or pulled using a variety of methods but once they are built and stored in the graph then they are not requested to be built again for the lifetime of that BuildSession. This means that for a given declarative request you will only ever have one object per type instantiated. If, like me, you are starting your application from a bootstrapper this effectively turns all of your objects into singletons.

Lets try the same scenraio in CastleWindsor.

WindsorContainer container = new WindsorContainer();
 
container.AddComponentWithLifestyle("Session", typeof(Session), LifestyleType.Transient);
container.AddComponentWithLifestyle("Model1", typeof(Model1), LifestyleType.Transient);
container.AddComponentWithLifestyle("Model2", typeof(Model2), LifestyleType.Transient);
container.AddComponentWithLifestyle("Shell", typeof(Shell), LifestyleType.Transient);
 
Shell shell = container.Resolve();
 
Assert.AreNotEqual(shell.Model1.Session, shell.Model2.Session);

This works, both data sessions are unique. Let’s try AutoFac.

var builder = new ContainerBuilder();
 
builder.Register().FactoryScoped();
builder.Register().FactoryScoped();
builder.Register().FactoryScoped();
builder.Register().FactoryScoped();
 
var container = builder.Build();
 
Shell shell = container.Resolve();
 
Assert.AreNotEqual(shell.Model1.Session, shell.Model2.Session);

Again this works as well.

How can this problem be solved by mere mortals? Well the most obvious solution would be to pass factories that can create your transient objects instead of just passing the transient objects themselves. However this is not ideal as it just leads to more code noise that should be handled by the DI component.

Can we use an interceptor? Unfortunately this approach does not work as your custom interceptor will be called only once per BuildSession resulting in the same problem. The same is true for using a ConstructorInstance. As this post ends I have been searching for a way of getting true instanced objects out of structuremap for most of a day with no success. In ending let me say that I am open to any expertise you may offer on this subject, and if I do find the answer I will most definitely post an update to this article.

Update
It would appear that there is no good way to do this using StructureMap. There is a workaround that though arduous could work for more limited scenarios. The trick is to define the dependency for the object that needs a transient type.

x.BuildInstancesOf()
    .TheDefault.Is.OfConcreteType().CtorDependency().Is( x.OfConcreteType() );

Though this works it wouldn’t be really practical if your dependency is used in numerous places. The reasons that the author chose to limit transients to only once per session are valid and advantageous for his situation but causes some problems elsewhere. What I would have preferred was that the BuildSession caching was done with an interceptor the same way as singleton caching. That way not every instance would be limited by the BuildSession caching and other implementations could be provided.

Update

As Bart Deleye pointed out in the comments the latest version of StructureMap now properly supports this scenario with the following syntax.

.ForRequestedType().TheDefaultIsConcreteType().AlwaysUnique()

Thus resulting in a very happy ending due to the flexibility and collaborative nature of open source software.  Thanks Jeremy

kick it on DotNetKicks.com

Creating clean testable code is one of the major challenges when creating complicated, composite user interfaces.  To help with this a variety of patterns have cropped up including MVC, MVP, and most notably for WPF the MVVM pattern.   These patterns work fine for the most part at least until your view gets a little bit too complicated.  What is a programmer supposed to do with the added complexity?  You should be separating common logic out into self contained controls, each with their own view models.  This is easier said then done, as you need to make sure that you provide view models for each of the controls your view implements.  While this is probably the more accepted way of doing things, it leads to a lot of code noise and increased complexity when writing tests for your main view model.

There is another way and you can get there by using the Markup Extensions that are available to exend WPF.  Because I’m a bit to lazy to create my own custom binding extension, I used one that I found here http://www.hardcodet.net/2008/04/wpf-custom-binding-class .  This fellow has already explored custom bindings and has created an easy to use base class for creating and manipulating custom WPF bindings.

With this class in place it is a fairly trivial operation to create a databinding class that utilizes your favorite dependency injector.  For this sample I am using StructureMap.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
    /// <summary>
    /// Binds to a dependency injected object
    /// </summary>
    public class DIBinding : BindingDecoratorBase
    {
        /// <summary>
        /// The type we are looking for
        /// </summary>
        public Type Type { get; set; }
 
        /// <summary>
        /// The key if applicable
        /// </summary>
        public string Key { get; set; }
 
        public override object ProvideValue(IServiceProvider provider)
        {
            //use DI to get the value
            if(Type == null)
                throw new InvalidOperationException("You must specify a type for this binding");
 
            Source = String.IsNullOrEmpty(Key) ? ObjectFactory.GetInstance(Type) : ObjectFactory.GetNamedInstance(Type, Key);
 
            return base.ProvideValue(provider);
        }
    }

Once we have created this binding helper we can use it in any xaml file provided that we include the proper namespaces of course.

1
<TreeView ItemsSource="{DataBinding:DIBinding Type=MainNav:IMainNavigationMenu, Path=MenuItems}" />

Use of dependency injection in your xaml files should be limited to where it is appropriate.  Of course it is not appropriate to do you whole application in this manner, but for certain controls it can lead to a much cleaner more testable view model for rest of your code.

Version 0.2.0.0 is Out!

October 24th, 2008

Ok I’ll admit that it’s a bit later than I would have liked, but the next version of NHibernate.Remote is out.  While I’m sure that you’d like to read a lengthy article about blah this, blah that, and how hard it was with all of the other demands at work; I just don’t feel like writing all that out here.  So let’s just start of with a list of things that have changed.

  • Linq queries are now supported
  • Criteria queries are now supported
  • All new enities can now be saved
  • Entities on the client are change tracked and the changes are automatically submitted with a flush
  • Many more methods of ISession are now working
  • Better session concurrency

However there are still things that are being worked on, most noteably.

  • Transactions
  • Filters
  • Named queries
  • Sql queries
  • Change tracking on collections
  • Attatching transient entities

For a more complete list check out the documentation.

The underlying mechanisms have changed and evolved considerably since the last version.  However bear in mind that because of the vast number of entity combinations and queries, I haven’t had a chance to write tests for every senario, especially the more complex ones.

If you are adventuresome, grab the binaries or the sample project from the downloads page and give it a try. This version requires NHibernate 2.0.1GA and if you are using the binaries only, you will also need Post Sharp.

Forums are here

October 23rd, 2008

Due to the number of comments that I have been getting on this blog and the emails that I have been receiving,  I have decided to setup a small forum for questions and comments.  Feel free to drop by and add your 2 cents on NHibernate.Remote, Generic Messaging or just anything in general.  I will try to answer any questions directed to me in a timely fashion (I hope).

Posted in Misc | No Comments »

Serialization bites again.

October 9th, 2008

I’ve been back working on NHibernate.Remote for the last week since I finished some of the more urgent updates for the company where I’m working.  I’ve come to the sad realization that the path I’ve been treading with the initial NHibernate.Remote codebase just won’t cut it for several reasons.

1) NHibernate needs a session factory.  You just can’t operate remotely or locally without a session factory.  Initially my goal was to transfer the required factory information across the wire to the remote client. However this approach doesn’t work very well as SessionFactory information is deeply nested and not conducive to serialization.  So I’ve opted for the next best thing which is to create an identical session factory on both ends of the wire.  That way both the server and the client can be aware of Entities, Collections and Proxies.  The only thing that the remote session factory does not get is a connection string, so it cannot be used to open a direct database connection.  So far this has been working fairly well and has enabled me to get both Criteria queries and NHibernate.Linq queries working over the wire.

2) That was the good news, now for the bad news.  The remote client simply needs to be aware of the entities that it is holding.  That means that every time an entity or a collection comes in over the wire it needs to affect the persistence context.  If this can be implemented flushing the remote session will become much easier.  I thought that the ObjectGraphWalker that I had created would be up to this task but once again I appear to be mistaken.   One of the requirements  I need is that I need to be able to replace an entity as I walk the object graph.  Let me explain further.  In a local NHibernate session if you query an object, change some properties and then query that object again, NHibernate is smart enough to detect that it already has that entity and will return to you the original changed object.  I need to do that remotely, thus the requirement for substituting objects when I walk an incoming graph.  That is simply impractical with the way that the ObjectGraphWalker works.

So I’m back to needing custom access to the inner workings of a serializer. I’ve tried to hack my way into the NetDataContractSerializer but with little success.  Surely my requirement is neither original or unique and Microsoft would do well to provide more open access to their serialization techniques.  Most likely I’ll just have to use reflector to extract the functionality that I need.  Sigh.