简体   繁体   English

Caliburn.micro与团结

[英]Caliburn.micro with unity

At the moment I'm learning more about caliburn.micro and it is amazing. 目前我正在学习更多关于caliburn.micro的内容,这真是令人惊叹。

In my small demo project with some navigation there is MEF and the EventAggregator. 在我的小型演示项目中,有一些导航,有MEF和EventAggregator。

As I want to use caliburn.micro in a project where unity is already in use, I want to use Unity for DI. 由于我想在一个已经使用统一的项目中使用caliburn.micro,我想使用Unity进行DI。

How can I set up the bootstrapper to use Unity? 如何设置引导程序以使用Unity?

Any good tutorials besides the MindScape tutorial and those on the codeplex page are very welcome. 除了MindScape教程和codeplex页面上的任何好的教程都非常受欢迎。 (except that I did not see the right one handling this case) (除了我没有看到处理这种情况的合适的人)

There are 4 methods you have to override in bootstrapper to wire the IoC container (when using Boostrapper<T> ): 在引导程序中必须覆盖4种方法来连接IoC容器(使用Boostrapper<T> ):

  1. Configure()

    That's usually where you initialize the container and register all dependencies. 这通常是初始化容器并注册所有依赖项的地方。

  2. 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 eg 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). 所以这里你的容器必须以某种方式获得一个基于string和/或Type的实例(通常是类型,当你使用视图优先绑定将模型连接到视图时使用字符串)。 Usually containers have similar methods built in, which work out of the box or need just a little adjustment. 通常容器内置类似的方法,开箱即用或只需稍微调整即可。

  3. 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. 检索对象集合(仅按类型) - 据我从经验中可以看出,这个通常由Caliburn.Micro用于视图。

  4. 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. 如果您有兴趣,我有一个使用SimpleInjector(或Autofac)的示例,遗憾的是我没有使用Unity的经验。

[EDIT] [编辑]

Sample time! 采样时间! This one is using SimpleInjector. 这个是使用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.
    }
}

I found the Wiki for CM very helpful, and coming from a Unity/CSL background the Bootstrapper<TRootModel> method names and signatures were intuitive. 我发现CMWiki非常有用,并且来自Unity / CSL背景的Bootstrapper<TRootModel>方法名称和签名非常直观。

I wanted to share my own Class UnityBootstrapper<TRootModel> which utilizes Unity 3, it's small, clean and does what you would expect. 我想分享我自己的Unity UnityBootstrapper<TRootModel> ,它使用Unity 3,它小巧,干净, 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;
    }
}

You can instance this directly, providing a valid generic type parameter, or you can subclass and customize things such as Lifetime Managers: 您可以直接实例化,提供有效的泛型类型参数,或者您可以子类化和自定义诸如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();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM