Prism.Forms 哪个 IoC 容器更好

Which IoC container is better with Prism.Forms

我正处于一个新的 Prism.Forms 项目的开始阶段,我想知道各种 IoC 容器 中的哪一个(AutofacDrylocNinjectUnity) 最好继续使用。

我不知道这是不是真的,但我在某处读到 Unity 不再处于积极开发状态,因为这个和 MEF 是唯一的 IoC 容器 我曾经使用过 我不确定它是否可行。

与此同时,我对 AutofacDrylocNinject 知之甚少或一无所知。

请objective提出任何建议,提供您认为其中一个比其他更好的原因,而不是简单地"I use xxx";我想做出明智的决定。

我能做的最好的事情就是按目前的情况安排事实。

注意: 自从我在 2017 年首次回答这个问题以来,发生了很多变化。以下信息不断更新,应该对您在项目上做出决定有所帮助.但是请注意,您现在也可以使用 Prism.Container.Extensions,因为它支持抽象许多非常强大的注册方法,包括工厂,并且能够将单个实现注册为不同服务的单例。可以在那里添加额外的容器。可在 https://prismplugins.com

中找到有关此内容的其他文档

支持的容器

这些是 Prism 团队正式运送的容器

DryIoc

这是我使用和推荐最多的容器。它正在积极开发中,速度非常快,并且与当前版本的 Prism 配合得很好。同样重要的是,当我有疑问或问题时,维护者会非常迅速地解决问题或回答我的问题。 Dadhi 还非常擅长主动为 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 的任何引用,然后更新 Prism.Unity.Forms 现在针对 Unity.Container NuGet 包而不是 Unity NuGet 包。您还应该注意,针对比 Prism 构建所针对的版本更新的 Unity 版本可能会破坏您的应用程序,因为 Unity 引入了许多重大更改,但没有从一个小补丁到另一个小补丁的解释或文档。

非官方支持

这些容器有可用的非官方包。这些可能适合您,也可能不适合您,风险由您自行承担。

Microsoft.Extensions.DependencyInjection

Prism 需要 Microsoft DependencyInjection 模式不支持的某些功能,例如可变性和命名服务。然而,有一个实现可以为 Prism.Container.Extensions 项目中的所有 Prism applications/platforms 提供通用支持。

生命周期结束/已弃用的容器

虽然多年来这些容器已在许多项目中使用,但 Prism 团队不再支持以下容器。

Autofac

尽管很受欢迎,但我通常不建议使用它。人们似乎对 API 很困惑。在 Prism 6.3 中,它的实现非常糟糕。遗憾的是,为了提高性能,Autofac 团队非常坚决地决定让容器不可变。从 Prism 7.1 开始,Prism 正式放弃了对该容器的支持。

Ninject

Ninject 长期以来一直是使用率最低的容器之一。随着团队转向支持 netstandard,这在 7.0 中从 Prism.Forms 中删除。虽然 Ninject 3.3 在技术上确实附带了 netstandard2.0 api,但它与 Xamarin 目标不兼容。它目前也处于非常不健康的状态,从 2017 年 11 月发布最新的 3.3 版本,从 2016 年 8 月发布最新的 4.0 预览版。

更新

值得注意的是,从 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 变得更容易,但这并不会消除您直接与底层容器交互的能力。要访问底层容器,您只需调用 GetContainer 扩展方法,您将能够执行 Prism 的 IoC 抽象不直接支持的任何更复杂的操作。

更新 2

Prism 7.2 围绕 IoC 抽象引入了一些 API 变化。值得注意的是,总的来说,这些更改不会影响大多数用户。但是,如果使用引用旧版本 Prism 的其他库,您可能会遇到二进制不兼容问题。

IoC 变化包括:

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