Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Caliburn.micro with unity

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)

like image 748
Mare Infinitus Avatar asked Dec 03 '22 23:12

Mare Infinitus


1 Answers

I found the Wiki for CM very helpful, and coming from a Unity/CSL background the Bootstrapper<TRootModel> method names and signatures were intuitive.

I wanted to share my own Class UnityBootstrapper<TRootModel> which utilizes Unity 3, it's small, clean and does what you would expect.

/// <summary>
/// <para>Unity Bootstrapper for Caliburn.Micro</para>
/// <para>You can subclass this just as you would Caliburn's Bootstrapper</para>
/// <para>http://caliburnmicro.codeplex.com/wikipage?title=Customizing%20The%20Bootstrapper</para>
/// </summary>
/// <typeparam name="TRootModel">Root ViewModel</typeparam>
public class UnityBootstrapper<TRootModel>
    : Bootstrapper<TRootModel>
    where TRootModel : class, new()
{
    protected UnityContainer Container
    {
        get { return _container; }
        set { _container = value; }
    }

    private UnityContainer _container = new UnityContainer();

    protected override void Configure()
    {
        if (!Container.IsRegistered<IWindowManager>())
        {
            Container.RegisterInstance<IWindowManager>(new WindowManager());
        }
        if (!Container.IsRegistered<IEventAggregator>())
        {
            Container.RegisterInstance<IEventAggregator>(new EventAggregator());
        }
        base.Configure();
    }

    protected override void BuildUp(object instance)
    {
        instance = Container.BuildUp(instance);
        base.BuildUp(instance);
    }

    protected override IEnumerable<object> GetAllInstances(Type type)
    {
        return Container.ResolveAll(type);
    }

    protected override object GetInstance(Type type, string name)
    {
        var result = default(object);
        if (name != null)
        {
            result = Container.Resolve(type, name);
        }
        else
        {
            result = Container.Resolve(type);
        }
        return result;
    }
}

You can instance this directly, providing a valid generic type parameter, or you can subclass and customize things such as Lifetime Managers:

public class AppBootstrapper
    : UnityBootstrapper<ViewModels.AppViewModel>
{
    protected override void Configure()
    {
        // register a 'singleton' instance of the app view model
        base.Container.RegisterInstance(
            new ViewModels.AppViewModel(), 
            new ContainerControlledLifetimeManager());

        // finish configuring for Caliburn
        base.Configure();
    }
}
like image 146
Shaun Wilson Avatar answered Dec 20 '22 02:12

Shaun Wilson