Unity & ObjectBuilder (part I)

This is a series of articles on Unity and ObjectBuilder (OB). Currently the OB is version 2 and Unity is version 1.1 (v1.2 is around the corner with the new interception mechanism).

I have written these articles in the first place because I needed to understand myself the inner treasures of Unity & OB. During this research I discovered that there is very, very little info/documentation and few people have either the courage to go deep into these frameworks or lack the time to write down what they have understood. The exception to the rule is the (now somewhat obsolete) series of articles on the Software Mechanics blog, which seems to have had the same pains as me in trying to understand the OB.

I’m not an expert and I don’t pretend I understand all of it now (especially the threading stuff is intrinsically hard to fathom) but I hope these field notes will help others to extend Unity (write Unity extensions) and to use the OB with more confidence.

The plan is the following. This first part will give an overview of Unity & OB. The second part goes into more details of how you can articulate OB to build stuff. The third part will deal with some concrete Unity extensions. The goal is to show you that creating (for example) something like the Microsoft Extensibility Framework (MEF) on top of Unity & OB is conceptually not difficult once you unsterstand the basic tenets.

This is a series of articles on Unity and ObjectBuilder (OB). Currently the OB is version 2 and Unity is version 1.1 (v1.2 is around the corner with the new interception mechanism).

I have written these articles in the first place because I needed to understand myself the inner treasures of Unity & OB. During this research I discovered that there is very, very little info/documentation and few people have either the courage to go deep into these frameworks or lack the time to write down what they have understood. The exception to the rule is the (now somewhat obsolete) series of articles on the Software Mechanics blog, which seems to have had the same pains as me in trying to understand the OB.

I’m not an expert and I don’t pretend I understand all of it now (especially the threading stuff is intrinsically hard to fathom) but I hope these field notes will help others to extend Unity (write Unity extensions) and to use the OB with more confidence.

The plan is the following. This first part will give an overview of Unity & OB. The second part goes into more details of how you can articulate OB to build stuff. The third part will deal with some concrete Unity extensions. The goal is to show you that creating (for example) something like the Microsoft Extensibility Framework (MEF) on top of Unity & OB is conceptually not difficult once you unsterstand the basic tenets.

The ObjectBuilder pipeline

We’ll first give an overview of OB and you’ll see in the next section how Unity hides much of the OB mechanisms to ease a developer’s life.

A bird’s eye view on the build process

The following picture is a helpful map you ought to keep in your mind when dealing with OB:

The big idea is the following:

an object is built through a series of actions, called strategies, which are executed in the order they have been added to the build process. Because you might need information to be passed from one action (strategy) to another, you need a bag into which you can save stuff (state info, parameters, whatever), this bag is a collection called policies. A policy can be anything you like, in fact the tagging interface is empty. A policy is however not something persistent, it lasts as long as the build process, so if you wish to keep stuff outside this timeframe you need another bag, which is the Locator. The locator is a place where you can look up stuff you need. Finally, once an object has been created (that is, the chain of strategies has procuded a final result) it can be kept in a container where all the created instances and type are saved for later. This container is the LifeTimeContainer.

You have to keep in mind that the OB is more a framework than a fully featured system. Unity can be seen as a facade on top of the OB which allows you to use various implementations. For example, the lifetime container allows you to make sure that an instance is a singleton, but by default the lifetime container will not do anything with the instance it only gives you a space in which you can manage things. Similar for the policy collection, it’s there but you will not have much pleasure of it unless you actively use/create stuff from/in it.

The Build class is your main entry point if you wish to build something inside OB and the BuilderContext is really just a wrapper for the parameters you pass into the Build instance. In fact, one has the following signature wherein you can see that the paramters passed are simply reorganized and the BuildUp method really delegates the action to the (head of the) chain:

1
2
3
4
5
6
7
8
9
10
11
public object BuildUp(IReadWriteLocator locator,
              ILifetimeContainer lifetime,
              IPolicyList policies,
              IStrategyChain strategies,
              object buildKey,
              object existing)
{
 
    BuilderContext context = new BuilderContext(strategies, locator, lifetime, policies, buildKey, existing);
    return strategies.ExecuteBuildUp(context);
}

So, building an object through OB amounts to a list of specifications (a context to be more precise) which we’ll describe next more in detail.

The OB ingredients

You are used to instantiate classes using the standard C# syntax but this doesn’t give you much grip on how it’s being constructed. For example:

  • maybe there are some constraints on the instance, maybe it should be a singleton
  • maybe there are security issues to be checked before the instance is created
  • maybe after the instance is created you need to assign property values
  • maybe the instance is part of a MVC context and you need to wire it to the controller or the model
  • maybe the instance will raise an exception in the constructor because some other object is NULL and you need to check this in advance

Obviously, you can do some pre- or post-processing and do the checks and assignments after the instantiation but this becomes a tiresome duty if you have lots of them. It’s not uncommon in a MVC setup to do lots of event and property bindings and to wire up lots of stuff on deserializations. So, a framework which automates this is a helpful shortcut and lifts your code to a higher level of uniformity and abstraction.

How to create an instance in OB? The most basic example is the following:

1
2
3
4
5
6
Builder builder = new Builder();
Locator locator = new Locator();
LifetimeContainer lifetime = new LifetimeContainer();
PolicyList policies = new PolicyList();
StrategyChain chain = new StrategyChain();
builder.BuildUp(locator, lifetime, policies, chain, typeof(MyClass), nul

As it stands this will return a NULL because the code contains all the OB ingredients but they’re all empty. Let me however first go a little deeper into what these ingredients are.

  • the Builder is the wrapper and main entry point in the construction process
  • the Locator is a (in essence) dictionary in which you can store stuff for later use or where you can look up things if necessary during the construction process. Note that, unless you pass this locator into every build, it will not by itself be persistent. As mentioned earlier, the OB framework is a toolbox. So, if you wish to use the Locator as a kind of repository for every build you need to create some more infrastructure and wrap the build process without having to create or look up the locator every time. The EntLib and Unity give you examples (wrappers of facades) of how to do this.
  • The Lifetime container is a IEnumerable list and can, hence, contain whatever is being created. Here again, this lifetime object does not do anything by itself, you need to control yourself what goes in and when it’s being disposed. For example, if you wish an object to be a singleton you need to write code which makes sure that the instance stored in the lifetime container is unique and a singleton strategy needs to break the construction process if a singleton instance has been created before. Unity has all this though, so don’t be alarmed.
  • the policy collection contains (once again) an open space for anything you need to pass on from strategy to strategy. For example, if constructor parameters needs to be fed into the strategy chain, then the Policy list is the place to store it.
  • the StrategyChain, finally, is the collection of actions to be performed in order to end up with a fully decorated instance. This chain represents, if you wish, an interpreter pattern or a meta description of some program to be run. We will dwell on what a strategy is below.

Strategies

A strategy is the place where the action takes place. But why having a chain of actions? The idea here is the same as the responsability pattern; whoever feels in charge picks it up. You check in the strategy if you need to act and if not then the action is taken over by the next one in the chain. If fact, the chain is traversed twice during the building process, once from head to tail calling the PreBuildUp method on each strategy and once from tail to head calling the PostBuildUp method on each strategy. This allows your strategy to do some post-processing even if it was created by another one.

The signature of a strategy hands over all you need and all there’s available through the buidler context:

1
2
3
4
5
6
7
public interface IBuilderStrategy
{
void PreBuildUp(IBuilderContext context);
void PostBuildUp(IBuilderContext context);
//we discard the TearDown mechanism for the sake of simplicity
//and because it's totally analog to the BuildUp mechanism.
}

Now, what if you want to break the chain of actions and your strategy decides the instantiation is finished? Easy, there is a BuildComplete property in the context which if set to true will break the loop. As an example, image the most basic strategy which simply breaks the instantiation without doing anything else:

1
2
3
4
5
6
7
8
9
10
11
12
13
class FirstStrategy : BuilderStrategy
{
    public override void PreBuildUp(IBuilderContext context)
    {
        Console.WriteLine("First strategy, prebuilding " + context.OriginalBuildKey);
        context.BuildComplete = true; //this will stop the chain of strategies
    }
 
    public override void PostBuildUp(IBuilderContext context)
    {
        Console.WriteLine("First strategy, postbuilding " + context.OriginalBuildKey);
    }
}

The result will be that nothing gets created, of course, but the sample is useful to demonstrate that even if you break the chain the reverse loop of PostBuildUp of methods will actually be performed. This can be seen in the implementation of the build up in the StrategyChain class (this is the default implementation of the chain which you can find in the Microsoft.Practices.ObjectBuilder2 namespace):

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
27
28
29
30
31
32
public object ExecuteBuildUp(IBuilderContext context)
{
    int i = 0;
    try
    {
        for(; i < strategies.Count; ++i)
        {
            if(context.BuildComplete)
            {
                break;
            }
            strategies[i].PreBuildUp(context);
        }
 
        if(context.BuildComplete)
        {
            --i; // skip shortcutting strategy's post
        }
 
        for(--i; i >= 0; --i)
        {
            strategies[i].PostBuildUp(context);
        }
        return context.Existing;
    }
    catch(Exception ex)
    {
        context.RecoveryStack.ExecuteRecovery();
        throw new BuildFailedException(
            strategies[i], i, context.BuildKey, ex);
    }
}

The crucial line being line 17 where the loop is set to start just before the strategy which has declared the process to be complete. One wonders why these methods were not implemented as events but anyway.

The next question is: how does a strategy know what to do and if it adds some stuff to an instance where is it placed? This information is part of the context where if you look at the definition of the IBuilderContext interface you’ll see

1
2
3
4
5
6
7
public interface IBuilderContext
{
    object OriginalBuildKey { get; }
    object BuildKey { get; set; }
    object Existing { get; set; }
    //more stuff left out for clarity
}

The OriginalBuildKey is the type which in the very beginning of the process was asked to be created. For example, if you would ask Unity to resolve a certain type you’d write:

1
2
3
IUnityContainer ctx = new UnityContainer();
ctx.Register< IMyObject , MyObject >();
MyObject obj = ctx.Resolve< IMyObject >();

in which case the original key would be ‘IMyObject’ and the BuildKey ‘MyObject’. Note that the OriginalBuildKey cannot be set but you do have the possibility in a strategy to alter the buildkey and map yourself the original key to something else.

Why is are the build keys objects and not types? Because you can ask the build process to create something on the basis of a string or whatever you like. If your strategy can map the incoming key to something which can add to the construction, then go ahead. Imagine, for instance, that the incoming key would be some XML which would act as a deserialized form of some object. It’s not something I would advice because the policies are there to place parametrizations in, but theoretically speaking you can use anything you like as a build key.

What about the instance, where is it place? The Existing property is the place where the instance is placed (and shared). In fact, there is a separate policy in charge for this called the LifeTimePolicy, which we’ll cover in the next article.

The Unity wrapper around OB

Now that you have a basic understanding of OB, let’s see how Unity simplifies all this.

First off, Unity is taking care of all the things I mentioned above, all that you need to be aware of is implemented in a box. This box, the UnityContainer handles for example the creation and insertion of the Locator whenever something is aksed to be created. Unity has all the strategies and policies you need to create singletons, arrays of instances, inject properties during the creation process, call methods after instantiation and much more. In a way, Unity is a collection of tools build on top of OB and it presents you with the most common needs while keeping the door open to extensions. These Unity extensions are, in fact, wrappers around strategies and policies being added to the OB underneath Unity.

Another stack of code you’ll find in Unity which extends OB is the possibility to configure the creation process through a configuration file. This does not really add anything new but merely converts an XML file to build process. If you prefer, this is a declarative way to create OB build processes, much like XOML files are a declarative way of defining a WF flow.

As an example of the wrapping in Unity, consider the Resolve method which allows you to create an instance of a registered class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private object DoBuildUp(Type t, object existing, string name)
{
    try
    {
        return new Builder().BuildUp(
            locator,
            lifetimeContainer,
            policies,
            GetStrategies(),
            new NamedTypeBuildKey(t, name),
            existing);
    }
    catch (BuildFailedException ex)
    {
        throw new ResolutionFailedException(t, name, ex);
    }
}

and compare this to the basic OB example above. You will immediately see that Unity simply inserts the key ingredients of OB into the Builder which have been instantiated in the constructor of Unity. Why do I so much emphasize this? Because the key to understanding Unity resides in the comprehension of the OB mechanism and does not represent on its own much new. In addition, you need to have a good grip on OB in order to write Unity extensions. While it might seem that Unity adds an additional layer of abstraction it in fact only converts stuff to make OB do its work. For example, the Dependency attribute in Unity allows you to tell Unity to assign an existing value to a property whereon the attribute is. There is nothing magical in what’s going on under the hood here. A strategy registered in Unity simple loops over properties of an instance (during a PostBuildUp loop) and checks for custom attributes. If the Dependency attrib is found Unity will look up in the lifetime container is there’s something available that can be injected. In a way, it’s just a combination of standard .Net reflection and OB mechanics. We will see in a later article that it’s in fact rather easy to add you own attribute-based injection mechanism.

While there’s much more to be said about Unity I will delay this till I explain in detail how to cook your own Unity extensions, in the third part of this series.

In the next part I’ll give you plenty of OB examples and do some wicked stuff in order to convince you that there’s nothing scary or difficult about OB & Unity.

Tagged with:
 

4 Responses to “Unity & ObjectBuilder (part I)”

  1. Link collection…

    Link collection…

  2. [...] is the third part (see part I & part II) of my series on Unity & ObjectBuilder. In fact, the previous introductory [...]

  3. [...] the first part of this series I gave you an overview of Unity and OB. In this article I have picked out some concrete examples [...]

  4. [...] Hinweis gab mir Erich Eichinger (Spring.NET) in der ALTNETDE Maillingliste, der mich auf die Seite http://www.orbifold.net/ des Authors Francois ‘Swa’ M.Vanderseypen führte. Er beschreibt hier schön in einem Artikel [...]

Leave a Reply