Caliburn.micro with unity

c#, caliburn.micro, unity-container, wpf

Solution

There are 4 methods you have to override in bootstrapper to wire the IoC container (when using `Boostrapper<T>`):

`Configure()`

That's usually where you initialize the container and register all dependencies.

`GetInstance(string, Type)`

Retrieval of the object by type and key - as far as I can tell it's usually used by framework to retrieve e.g. view models, regular dependencies. So here your container has to somehow get an instance based on a `string` and/or `Type` (usually type, string is used when you wire the model to the view using view-first binding). Usually containers have similar methods built in, which work out of the box or need just a little adjustment.

`GetAllInstances(Type)`

Retrieval of collection of objects (by type only) - again, as far as I can tell from experience, this one is usually used by Caliburn.Micro for views.

`BuildUp(object)`

A method where you can do property injection on an object.

If you're interested, I have a sample which uses SimpleInjector (or Autofac), unfortunately I have no experience with Unity.

[EDIT]

Sample time! This one is using SimpleInjector.

public class MainViewModel
{
//...
}

public class ApplicationBootstrapper : Bootstrapper<MainViewModel>
{
    private Container container;

    protected override void Configure()
    {
        container = new Container();

        container.Register<IWindowManager, WindowManager>();
      //for Unity, that would probably be something like:
      //container.RegisterType<IWindowManager, WindowManager>();
        container.RegisterSingle<IEventAggregator, EventAggregator>();

        container.Verify();
    }

    protected override object GetInstance(string key, Type service)
    {
        // Now, for example, you can't resolve dependency by key in SimpleInjector, so you have to
        // create the type out of the string (if the 'service' parameter is missing)
        var serviceType = service;
        if(serviceType == null)
        {
            var typeName = Assembly.GetExecutingAssembly().DefinedTypes.Where(x => x.Name == key).Select(x => x.FullName).FirstOrDefault();
            if(typeName == null)
                throw new InvalidOperationException("No matching type found");

            serviceType = Type.GetType(typeName);
        }

        return container.GetInstance(serviceType);
        //Unity: container.Resolve(serviceType) or Resolve(serviceType, name)...?

    }

    protected override IEnumerable<object> GetAllInstances(Type service)
    {
        return container.GetAllInstances(service);
        //Unity: No idea here.
    }

    protected override void BuildUp(object instance)
    {
        container.InjectProperties(instance);
        //Unity: No idea here.
    }
}

Problem

At the moment I'm learning more about caliburn.micro and it is amazing. In my small demo project with some navigation there is MEF and the EventAggregator. As I want to use caliburn.micro in a project where unity is already in use, I want to use Unity for DI. How can I set up the bootstrapper to use Unity? Any good tutorials besides the MindScape tutorial and those on the codeplex page are very welcome. (except that I did not see the right one handling this case)

Original source