Feeds:
Posts
Comments

Archive for March, 2008

I’ve been working on that IoC container I’ve blogged about.  You know, the ultra-lightweight, delegate based at the root with reflection as optional, simple container.  While doing so, I’ve also been learning about some of the other capabilities in other containers.  One of the things I discovered was Guice and the "annotation" (that would be an attribute for us .NET developers) based configuration it uses.  By itself, not all that exciting as I’d already expected to use attributes for specifying what to inject.  But then I noticed that they allow you to annotate an interface.  Wow.  Now the following is working with my container.

ObjectContainer container = new ObjectContainer();
container.RegisterDynamicConstruction();
IFoo foo = container.Resolve<IFoo>();

No, nothing was left out there (other than the definition of IFoo and some other class that implements it).  I’ve done no configuration.  I just registered dynamic construction which allows the container to create types that haven’t been registered by using reflection.  Then I instantiated an IFoo.  Resolve looked for a registered factory for IFoo, and when it didn’t find one it looked at the attributes on IFoo to discover a "default" implementation type and instantiated that.  This eliminates 90% of what I dislike about IoC containers.  You don’t have to specify a long list of configurations (in code or in some config file, doesn’t really matter) to register types with the container even though 90% of the time you’ll want the same type.  Why should I configure a container, just because I may want to mock a service out during testing?

Granted, I’m still specifying what types to create.  However, it’s done in code, when defining the interface, and is applied any time I use that interface (unless overriden) in every application with out doing any further configuration.  Nearly nirvana.

Unity (as well as other containers) may have this capability… I haven’t looked that close.  It does allow you to instantiate concrete types through reflection, which will still do injection, so it wouldn’t surprise me too much if they went the extra few inches to this.  If not, I believe it could be trivially added through an extension. So, the only major difference with what I’m building is the complexity/size.  So there’s probably not a lot of interest in what I’m building to other folks.  But I want it, and it’s been a fun project for discovery.

Read Full Post »

A while ago, I wrote a blog that was critical of the Unity IoC container.  A lot of what I wrote I think still stands.  One complaint, though, does need a (partial) retraction.  I complained that Unity was reflection based instead of being delegate based.  Well, this is true of Unity proper, but the Unity project includes a StaticFactoryExtension which provides an extension to do delegate based construction.  This can be used like this:

container.Configure<IStaticFactoryConfiguration>().RegisterFactory<SqlConnection>(() => new SqlConnection());

This is very flexible, and does provide full functionality.  It’s disappointing (to me) that the base functionality is reflection based, and an extension is required to use delegates (after all, the above syntax is a bit ugly), but at least the functionality is there.  Still not what I’d consider a "light weight" IoC container, and I’m still hoping to see some IoC interfaces in the BCL, but this isn’t a bad container.

Anyway, because it’s still not my ideal container and since I need a container for the M-V-Poo library I’m working on, I’ve been working on my own container.  I have a long way to go, to ensure the proper balance of features while maintaining a very lightweight code base, but I thought I’d share some of what I’ve come up with.  So, in this blog post I’m going to provide the basis for a lightweight container that you can extend into a container that fits your needs.  Before we begin, I’ll point out that there are a couple of other simple containers you can find in other blogs.  This one is slightly different in design (and heavier), because I’m focusing on providing a lightweight container while still providing all of the plumbing necessary to extend it until it provides all of the same functionality as Unity and other larger containers.

I’ll start with the container interface.  As I said in my critic of Unity, I’d prefer separate interfaces for both the locator and the container.  However, I’m keeping things simple here and providing only a single interface.  I’m also following some of the naming conventions from Unity, though this is not a clone of the Unity APIs.  When designing the interface for the container, I provided only the most verbose version of each function.  The other overloads are just convenience versions, and so I’m keeping them out of the interface.  That might sound odd right now, but you’ll see in a moment that this is actually a fairly flexible design.  That said, here’s the interface.

public delegate object ObjectFactoryCallback(IObjectContainer container);

public interface IObjectContainer
{
    IObjectContainer RegisterType(Type type, string name, ILifetimePolicy liftetime, ObjectFactoryCallback callback);
    object Resolve(Type type, string name);
    IEnumerable<object> ResolveAll(Type type);
}

Oh, there’s an ILifetimePolicy type in there that we’ve not defined yet.  Let’s look at it.

public interface ILifetimePolicy
{
    object GetValue(IObjectContainer conatiner, ObjectFactoryCallback callback);
}

If you’ve seen Unity, most of what’s here should be obvious.  This is a minimalist design, with all of the fluff removed.  Further, you’ll notice that RegisterType is delegate based instead of reflection based by the lack of a second Type parameter and the addition of an ObjectFactoryCallback delegate parameter.  So, we have a very simple interface design, now let’s provide an implementation.

public sealed class ObjectContainer : IObjectContainer
{
    private class Registration
    {
        public Registration(ObjectFactoryCallback callback, ILifetimePolicy lifetime)
        {
            Callback = callback;
            LifetimePolicy = lifetime;
        }

        public ObjectFactoryCallback Callback { get; set; }
        public ILifetimePolicy LifetimePolicy { get; set; }
    }

    private ObjectContainer _parent;
    private Dictionary<Type, Dictionary<string, Registration>> _registry = new Dictionary<Type, Dictionary<string, Registration>>();

    public ObjectContainer()
    {
    }

    public ObjectContainer CreateChildContainer()
    {
        ObjectContainer child = new ObjectContainer();
        child._parent = this;
        return child;
    }

    #region IObjectContainer Members

    public IObjectContainer RegisterType(Type type, string name, ILifetimePolicy liftetime, ObjectFactoryCallback callback)
    {
        Dictionary<string, Registration> registrations;
        if (!_registry.TryGetValue(type, out registrations))
        {
            registrations = new Dictionary<string, Registration>();
            _registry[type] = registrations;
        }

        Registration registration = new Registration(callback, liftetime);
        registrations[name ?? string.Empty] = registration;

        return this;
    }

    public object Resolve(Type type, string name)
    {
        object result = TryResolve(type, name);
        if (result == null && _parent != null)
            result = _parent.Resolve(type, name);
        return result;
    }

    public IEnumerable<object> ResolveAll(Type type)
    {
        Dictionary<string, Registration> registrations;
        if (_registry.TryGetValue(type, out registrations))
        {
            foreach (Registration registration in registrations.Values)
            {
                yield return Resolve(registration);
            }
        }
    }

    #endregion

    private object TryResolve(Type type, string name)
    {
        Dictionary<string, Registration> registrations;
        if (!_registry.TryGetValue(type, out registrations))
            return null;

        Registration registration;
        if (!registrations.TryGetValue(name ?? string.Empty, out registration))
            return null;

        return Resolve(registration);
    }

    private object Resolve(Registration registration)
    {
        if (registration.LifetimePolicy != null)
            return registration.LifetimePolicy.GetValue(this, registration.Callback);
        return registration.Callback(this);
    }
}

There you go, a complete IoC container that can be easily extended to have the full capabilities of Unity and other containers.

OK, I won’t leave you hanging.  Obviously when given just this, it seems like a very poor implementation.  Even for only a delegate based container, the convenience overloads are missing, which seems like it would make this awfully cumbersome to use.  And I’m sure several of you are confused about how you could possibly extend this container.  There’s no built in extension mechanism, like there is in Unity, and the container is sealed, for Pete’s sake.  Well, don’t worry, I’ll provide more.

First, I’ll explain how to extend this.  Instead of derivation or a fancy extension mechanism, I’m going to use extension methods.  I created an ObjectContainerExtensions static class where I provided a host of extensions.  First, let’s look at how you’d define some of the convenience overloads.

public static IObjectContainer RegisterType(this IObjectContainer self, Type type, ObjectFactoryCallback callback)
{
    return self.RegisterType(type, null, null, callback);
}
public static IObjectContainer RegisterType<T>(this IObjectContainer self, ObjectFactoryCallback callback)
{
    return self.RegisterType(typeof(T), null, null, callback);
}

Pretty simple, really.  From those two examples, you should be able to implement all of the the other convenience methods.  One very nice benefit here is that any IObjectContainer concrete type will get the added benefit of these methods with out having to implement anything.

OK, now what about instance registration?  We’ll write another extension method for that, with a few convenience overloads (I’ll leave the overloads as an exercise for the reader).

public static IObjectContainer RegisterInstance(this IObjectContainer self, Type type, string name, object instance)
{
    return self.RegisterType(type, name, null, c => instance);
}

This starts to show off the power of the delegate based approach.  Our concrete container only knows how to register a delegate, yet we’ve trivially implemented an extension method that allows you to register an instance.

Great, now what about adding reflection based registration?  How can I possibly do that with only a delegate based container?  Why, with some extension methods, of course.  I’ll start with an InjectProperties method that’s similar in usage to the BuildUp method in Unity.  It injects properties on an existing object by using reflection and looking for properties marked with an InjectAttribute (left as an exercise for the reader).

public static object InjectProperties(this IObjectContainer self, string name, object existing)
{
    Type type = existing.GetType();
    PropertyInfo[] properties = type.GetProperties();
    foreach (PropertyInfo propertyInfo in properties)
    {
        object[] inject = propertyInfo.GetCustomAttributes(typeof(InjectAttribute), true);
        if (inject != null && inject.Length > 0)
        {
            object value = self.Resolve(propertyInfo.PropertyType, name);
            propertyInfo.SetValue(existing, value, null);
        }
    }
    return existing;
}

Again, you can provide convenience overloads for this.

Now we have the functionality we need to do property injection via reflection, but we still need a way to do constructor injection.  Obviously the Resolve method should do this, but we can’t extend that beyond providing special delegates when we register a type with the container.  So, I’ll add a couple of private static methods that we’ll use as the implementation of our delegates later on.  I’ll also provide a private static method that can be used to create an ObjectFactoryDelegate that constructs a Type via reflection.

private static ConstructorInfo FindConstructor(Typetype)
{
    ConstructorInfo[] constructors = type.GetConstructors();
    if (constructors.Length == 0)
        throw newInvalidOperationException();

    ConstructorInfo constructorInfo = constructors[0];
    if (constructors.Length > 1)
    {
        int argCount = -1;
        bool injectFound = false;
        foreach (ConstructorInfo cur inconstructors)
        {
            object[] inject = cur.GetCustomAttributes(typeof(InjectAttribute), false);
            if (inject != nul l&& inject.Length > 0)
            {
                if (injectFound)
                    throw newInvalidOperationException();
                constructorInfo = cur;
                injectFound = true;
            }
            if (!injectFound)
            {
                ParameterInfo[] parameters = cur.GetParameters();
                if (parameters.Length > argCount)
                {
                    constructorInfo = cur;
                    argCount = parameters.Length;
                }
            }
        }
    }

    return constructorInfo;
}

private static object Create(IObjectContainer container, ConstructorInfo constructorInfo)
{
    ParameterInfo[] parameters = constructorInfo.GetParameters();
    if (parameters.Length == 0)
        return constructorInfo.Invoke(null);

    object[] parameterValues = new object[parameters.Length];
    for (int i = 0; i < parameters.Length; ++i)
    {
        parameterValues[i] = container.Resolve(parameters[i].ParameterType);
    }
    return constructorInfo.Invoke(parameterValues);
}

private static ObjectFactoryCallback TypeFactoryAdapter(Typetype)
{
    ConstructorInfo constructorInfo = FindConstructor(type);
    if (constructorInfo == null)
        throw new InvalidOperationException();

    return c =>
    {
        object result = Create(c, constructorInfo);
        return c.InjectProperties(result);
    };
}

Given this private implementation, we can now provide the RegisterType overloads for reflection based construction (again, most of the overloads are left for the reader to do).

public static IObjectContainer RegisterType(this IObjectContainer self, Type from, Type to, string name, ILifetimePolicy lifetime)
{
    return self.RegisterType(from, name, lifetime, TypeFactoryAdapter(to));
}

There you go, a lightweight container that provides a good portion of the functionality found in Unity.  There’s plenty of room for improvement.  The code provided is not production worthy yet, and there’s still functionality missing.  For instance, Unity will construct a type through reflection even if the type isn’t registered with the container.  All you do is call Resolve with a concrete class type, and the container will construct it and do appropriate injections.  With the current code, it’s non-trivial to do this, because we’ve hard-coded the reflection into our ObjectContainerExtensions class.  To keep this lightweight, I’d move that functionality out into it’s own extension class, and put it into a different namespace.  This allows anyone to use the functionality when implementing extensions, but keeps them out of the normal view for consumers.

Oh, there’s one final thing to illustrate.  You’ve seen the ILifetimePolicy interface, but how do you implement a policy?  Here’s the requisite SingletonLifetimePolicy.

public class SingletonLifetimePolicy : ILifetimePolicy
{
    private object lockObject = new object();
    private object value;

    #region ILifetimePolicy Members

    public object GetValue(IObjectContainer container, ObjectFactoryCallback callback)
    {
        if (value == null)
        {
            lock (lockObject)
            {
                if (value == null)
                {
                    value = callback(container);
                }
            }
        }
        return value;
    }

    #endregion
}

I considered other designs here.  Initially, I just provided delegate adapters instead of providing an ILifetimePolicy.  This works great, but I think the usage would be a little foreign to a lot of C# developers who’ve never done any functional programming.  I also considered designing the ILifetimePolicy interface so that it had an Adapt method instead of a GetValue method.  This makes the API familiar to the user, but the policy developer still has to understand functional programming.  I’m thinking that might be the more appropriate compromise, since it removes the concern about user’s reusing a policy instance in multiple RegisterType calls, which as you can see from the implementation above would simply not work.  With a functional design, it’s not too difficult to provide implementations that are safe from this.  I’m pretty sure I’ll go with that design in my own library, but I kept the implementation here simple, in order to not detract from the lessons meant to be learned.

Read Full Post »

Prism Drop 03-12-2008

In case you haven’t heard, Prism has it’s first drop available.  Prism is the Pattern’s & Practices next take on "composite applications", which are a very specific form of M-V-Poo.  Obviously, I’m interested in M-V-Poo, especially as the patterns apply to WPF.  I’ve been tracking Prism for a while now, and I’ve commented on the spikes and other information leaked to us in the past, so some of you have some idea what to expect out of this post ;).  Well, I might surprise you a little, actually.

This drop of Prism, though not with out serious design problems from my point of view, actually is fairly promising.  One of the most important design criteria I had for a framework such as this was actually a design goal of Prism: that it be lightweight (not an all-imposing framework, limited "Prism stuff" footprint in your applications and limited number of abstractions with a small API surface area).  Looking at the StockTrader reference application’s source, I’d say they’ve done a fair job with it.  In my opinion, the code for this application is a bit of a spaghetti mess.  It took me a while to understand the flow and relationships/responsibilities of the various classes.  I simply would have structured the code differently.  However, the lightweight nature of the emerging framework (it’s not yet a framework) looks like it would allow for using the concepts in an application structure more like I would prefer (specifics one what I’d prefer aren’t important here).

Currently, the reference application is leaning very heavily on the UnityContainer and Dependency Injection.  For those who have their own favorite DI container, don’t fear, you’re not locked into UnityContainer.  However, I still strongly believe that DI is overused, and there are certainly applications that would prefer to not have to deal with this concept at all.  So, I hope the emphasis on this pattern can be reduced.  At the very least, there should be no requirements for DI within the framework, even if the reference applications rely on it.  Since there’s no framework yet, I can’t say for sure wether or not there currently is such a dependency.

My one major complaint so far is that there’s currently no solution to my one big complaint with WPF in general: event handling requires codebehind.  I’m a very firm believer that the declarative approach with strong data binding is the most important aspect of WPF and other competing technologies, such as XUL.  This enables very rapid UI development, and allows the UIs to be done by designers (using design tools) instead of developers (using code editors).  Not that I don’t believe many people will fill both roles, mind you.  The one major failing with this in WPF from my point of view is that we don’t have a useful equivalent to data binding for events.  In XAML, event handlers (and this includes command handlers) can only specify methods that exist in the codebehind.  There’s a couple of problems with this.  First, the codebehind is very tightly coupled to the XAML (they are part of the same partial class!), which makes it awkward to maintain the separation between design and development.  In fact, it almost requires the designer to be enough of a developer to be able to create the handlers and implement them to call into the business objects.  Otherwise, the developer and designer can wind up in a situation where they step on each other’s toes.  This isn’t the end of the world, as we’re still in a much better situation here than we’ve ever been in the past, but I want full separation!  Then there’s the other problem with this, namely that a good portion of the time you want events to be handled by other objects and it’s awkward even for one person to have to create little stub handlers in the codebehind just to bridge between the two.

The reference application punts here.  All the Views create stub event handlers in their codebehinds, which then raise specific events published from the View that the Presenters (or anyone else) can subscribe to.  Obviously this works, and is the easiest (and a very flexible) solution.  But the amount of tedious code required is depressing, even if you don’t mind using codebehind, like I do.  This is the ONE thing I absolutely demand from an M-V-Poo framework.  (Actually, I’d much prefer a solution in WPF proper for this, but as long as we don’t have a solution there, any M-V-Poo framework I’d choose to use would need to supply a solution.)  There were a few concepts that were included in the spikes, that aren’t used in the reference application, that seemed to be attempts to address this issue.  In particular, I’m referring to the CommandDispatcher stuff.  Unfortunately, I found that to be a very poor answer.  First, it wasn’t general enough, only allowing you to handle Commands (and RoutedUICommands at that, due to a reliance on the Name property in a way that I don’t think is reliable, since I’m not aware of any requirements for this property to contain a unique value).  I demand a solution that will work with any event.

Wouldn’t it be ideal if WPF proper included an EventBinding markup extension with capabilities similar to the Binding markup extension, but which created event bindings instead of data bindings?

<Button Click="{EventBinding Source={StaticResource MyBusinessObject}, Handler=OnButtonClicked}"/>

With this, M-V-Poo would be trivial to implement any way you decided you wanted to implement it.  Unfortunately, I don’t believe it’s possible to implement such a markup extension today, and thus it has to be implemented within WPF proper.  But oh how I wish we had this today!!!  If any WPF framework developers at Microsoft read this, please consider something like this and do anything you can to get it into this summer’s service release!  If you want to discuss the concept, please reply here.

Any way, overall, even though Prism isn’t the M-V-Poo I’d build, I think they’re off to a better start than I originally gave them credit for.  It’s very possible this will evolve into something that, even if it’s not my M-V-Poo, it might allow me to implement my M-V-Poo.

Read Full Post »