2013-03-31 42 views
3

目前我正在学习更多关于caliburn.micro的知识,它很棒。Caliburn.micro with unity

在我的一些导航小演示项目中有MEF和EventAggregator。

因为我想在已经使用unity的项目中使用caliburn.micro,所以我想使用Unity for DI。

如何设置引导程序以使用Unity?

除了MindScape教程和codeplex页面上的任何优秀教程都非常受欢迎。 (但我没有看到正确的处理这种情况下)

回答

7

有4种方法,你必须在引导程序接线IoC容器覆盖(使用Boostrapper<T>时):

  1. Configure()

    这通常是您初始化容器并注册所有依赖项的位置。

  2. GetInstance(string, Type)

    按类型和主要对象的检索 - 据我可以告诉它通常使用的框架来如查看模型,定期依赖。因此,您的容器必须以某种方式获取基于string和/或Type(通常为type,使用视图优先绑定将模型连接到视图时使用的字符串)的实例。通常情况下,容器内置了类似的方法,可以在箱子外面工作,或者只需稍作调整。

  3. GetAllInstances(Type)

    对象(按类型只)的集合检索 - 再次,据我从经验来看,这是一个用于通常的看法使用Caliburn.Micro。

  4. BuildUp(object)

    的方法,你可以做一个对象的属性注射。

如果你有兴趣,我有一个使用SimpleInjector(或Autofac)样本,不幸的是我有统一的经验。

[编辑]

采样时间!这个使用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. 
    } 
} 
+0

是的,任何样品是好的,因为我知道团结我可能会看到我必须改变。 –

+0

@MareInfinitus我编辑了答案... –

+0

非常感谢。必须查看我是否真的需要GetAllInstances和BuildUp,或者是否有空的实现就足够了。我明确地不使用属性注入。也许Caliburn需要它在某个地方。 –

7

我发现Wiki for CM非常有帮助,从团结/ CSL背景来的Bootstrapper<TRootModel>方法名和签名是直观的。

我想分享我自己的类UnityBootstrapper<TRootModel>它利用Unity 3,它很小,干净,做你期望的。

/// <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; 
    } 
} 

可以将背景这直接提供有效的泛型类型参数,或者你也可以继承和定制的东西,如终身经理:

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(); 
    } 
} 
+0

谢谢!会试试这个! –