Caliburn.micro与团结

时间:2013-03-31 19:43:31

标签: c# wpf unity-container caliburn.micro

目前我正在学习更多关于caliburn.micro的内容,这真是太棒了。

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

因为我想在一个已经使用统一的项目中使用caliburn.micro, 我想将Unity用于DI。

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

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

2 个答案:

答案 0 :(得分:8)

在引导程序中必须覆盖4种方法来连接IoC容器(使用Boostrapper<T>时):

  1. Configure()

    这通常是初始化容器并注册所有依赖项的地方。

  2. GetInstance(string, Type)

    按类型和密钥检索对象 - 据我所知,它通常被框架用于检索,例如查看模型,定期依赖。所以这里你的容器必须以某种方式获取基于string和/或Type的实例(通常是类型,当你使用视图将模型连接到视图时使用字符串 - 第一次绑定)。通常,容器内置了类似的方法,开箱即用或只需稍微调整即可。

  3. GetAllInstances(Type)

    检索对象集合(仅按类型) - 就我从经验中可以看出,这个通常由Caliburn.Micro用于视图。

  4. BuildUp(object)

    一种可以对对象进行属性注入的方法。

  5. 如果您有兴趣,我有一个使用SimpleInjector(或Autofac)的示例,遗憾的是我没有使用Unity的经验。

    [编辑]

    抽样时间!这个是使用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.
        }
    }
    

答案 1 :(得分:8)

我发现Wiki for CM非常有用,来自Unity / CSL背景的Bootstrapper<TRootModel>方法名称和签名非常直观。

我想分享我自己的使用Unity 3的Class UnityBootstrapper<TRootModel>,它很小,很干净,可以满足你的期望。

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

您可以直接实例化,提供有效的泛型类型参数,或者您可以子类化和自定义诸如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();
    }
}