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)