使用Prism.Forms,哪个IoC容器更好

时间:2017-04-27 17:35:17

标签: xamarin.forms inversion-of-control ioc-container prism-6

我正处于一个新的Prism.Forms项目的开头,我想知道哪个IoC 容器AutofacDrylocNinjectUnity)最好继续推进。

我不知道这是否属实,但我在某处读到Unity已不再处于活跃开发状态,因此MEF是唯一的IoC 容器我曾经使用过,我不确定是否是要走的路。

与此同时,我对AutofacDrylocNinject知之甚少。

请客观地提出任何建议,说明为什么你觉得一个人比其他人好,而不仅仅是#34;我使用 xxx &#34 ;;我想做出明智的决定。

1 个答案:

答案 0 :(得分:48)

我能做的最好的事情就是按照目前的情况来布局事实。

DryIoc 是我使用和推荐最多的容器。它正处于积极的发展阶段,速度非常快,并且与目前的Prism版本配合得很好。同样重要的是,当我遇到问题或问题时,维护者可以非常快速地解决问题或回答我的问题。由于所有这些原因,我继续推荐容器。与Unity不同,API往往非常稳定,而且我还没有将DryIoc的更新问题超出了Prism的特定版本的目标。

Unity 是最受欢迎的容器,因为它是Brian多年来使用的容器,它是模板中第一个(也是很长一段时间)容器。它已经花了很长时间而没有被维护,但是该项目确实有一个新的维护者。值得注意的是,Unity 5中存在许多重大变化,这使得使用Prism 6.3升级到Unity 5是不可能的。然而,Prism已经在Prism 7的所有平台上更新到Unity 5.然而,Unity在基准性能方面也是平均水平。对于那些从Prism 6.X升级到Prism 7的注意事项,请注意您应该卸载对Unity或Common Service Locator的任何引用,然后更新现在以Unity.Container NuGet包而不是Unity NuGet包为目标的Prism.Unity.Forms。您还应该注意,针对较新版本的Unity而不是Prism构建的版本可能会破坏您的应用程序,因为Unity已经引入了许多重大更改,而没有从Minor Patch到Minor Patch的说明或文档。

Autofac ,尽管很受欢迎,但我通常会建议不要使用它。人们似乎对API非常困惑。在Prism 6.3中,它的实现非常糟糕。 Prism 7引入了几个重大变化,并为您提供了PrismApplication使用的ContainerBuilder,解决了很多注册问题。因为Autofac社区坚持要使容器不可变,所以它总是一个我建议不要使用的容器。虽然它适用于基本应用程序,但它会阻止您使用更高级的Prism功能,如Modularity。注意:在Prism 7.1发布之后,Prism团队决定停止对Autofac Container的所有进一步支持。 Prism团队认为,如果Container不能支持Prism提供的所有特性和功能,那么它不应该是官方支持的容器。

Ninject(DEPRECATED)没问题。它肯定是最少使用的容器,并且从各种容器的基准测试来看,它也是最慢的。 Prism 6.3使用了Portable.Ninject,这似乎是一个死的项目。 Prism 7.0试图利用最初针对NetStandard2.0的官方Ninject项目。由于Ninject Container与Xamarin Android和Xamarin iOS之间存在根本不兼容,后来对该容器的支持完全被撤销。

DryIoc 是我使用和推荐最多的容器。它正处于积极的发展阶段,速度非常快,并且与目前的Prism版本配合得很好。同样重要的是,当我遇到问题或问题时,维护者可以非常快速地解决问题或回答我的问题。由于所有这些原因,我继续推荐容器。与Unity不同,API往往非常稳定,而且我还没有将DryIoc的更新问题超出了Prism的特定版本的目标。

更新

值得注意的是,从Prism 7的预览5开始,我们已经抽象了容器。这将最终使您更容易在您选择的容器之间切换,因为API在如何注册您的服务和视图方面完全相同。您仍然可以访问Container,如果是Autofac,则可以通过扩展方法访问ContainerBuilder,以便您可以完成更复杂的注册。

// Prism 6.X way of Registering Services
protected override void RegisterTypes()
{
    // Container Specific Registrations

    // Autofac
    Builder.RegisterType<DebugLogger>().As<ILoggerFacade>().SingleInstance();

    // DryIoc
    Container.Register<ILoggerFacade, DebugLogger>(reuse: Reuse.Singleton,
                                                   ifAlreadyRegistered: IfAlreadyRegistered.Replace);

    // Ninject
    Container.Bind<ILoggerFacade>().To<DebugLogger>().InSingletonScope();

    // Unity
    Container.RegisterType<ILoggerFacade, MCAnalyticsLogger>(new ContainerControlledLifetimeManager());
}

// Unified API in Prism 7
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
    containerRegistry.RegisterSingleton<ILoggerFacade, DebugLogger>();
}

同样重要的是要记住,虽然Prism的IoC抽象使得更加统一的API变得更容易,但这并没有消除您与底层Container直接交互的能力。要访问底层容器,您只需调用GetContainer扩展方法,就可以执行Prism的IoC抽象不直接支持的任何更复杂的操作。

更新2

Prism 7.2引入了围绕IoC抽象的一些API更改。值得注意的是,这些更改通常不会影响大多数用户。但是,如果使用其他引用Prism的库,例如Prism.Plugin.Popups,则可能会遇到二进制不兼容问题,而这些库并不是针对7.2构建的。

IoC的变化包括:

  • Fluent API
  • 检查服务是否已注册的功能
  • 添加了允许瞬态和单身服务成为命名服务的方法
  • 添加了使用指定实例解析服务的功能。