【问题标题】:Connect third-party dependency injection framework with ReactiveUI用 ReactiveUI 连接第三方依赖注入框架
【发布时间】:2015-12-01 04:36:14
【问题描述】:

我正在检查 ReactiveUI MVVM 框架。我真的很喜欢 Rx 概念,并想在我的下一个项目中开始使用和学习它。

我在尝试将它与 Ninject 或第三方 DI 容器一起使用时发现缺少文档。

我通常做的是在平台应用层设置 Ninject 并在那里注册依赖项。然后使用它通过构造函数注入依赖项,或者在需要时通过服务位置解析它们。

我发现这种可选的构造函数依赖模式非常好,使构造函数中的依赖成为可选的,如果使用服务位置解析 null,则可以在单元测试时注入模拟依赖。

假设你有这个构造函数。

public OrdersListViewModel(IWebOrdersRepository<Order> webOrdersRepository = null)
        {
            _webOrdersRepository = webOrdersRepository ?? Locator.Current.GetService<IWebOrdersRepository<Order>>();
        }

这是使用 Splat 服务定位器,但我想使用 Ninject 构造函数注入和服务定位。

我在iOS平台项目中做的如下。

public class NinjectConfiguration : NinjectModule
    {
        public override void Load()
        {
            BindImplementations ();
        }

        private void BindImplementations()
        {
            Bind<IWebOrdersRepository<Order>> ().To<WebOrdersRepository> ().InSingletonScope();
            Bind<OrdersListViewModel>().ToSelf();
        }
    }

在 AppDelegate.cs 中。

NinjectKernel.Initialize(new NinjectConfiguration());

我在 UIViewController ViewDidLoad 方法中创建了一个 OrdersListViewModel。

public override async void ViewDidLoad()
        {
            base.ViewDidLoad();

            ViewModel = await BlobCache.LocalMachine.GetOrCreateObject(OrdersListViewModel.Key, () => {
                return NinjectKernel.Get<OrdersListViewModel>();
            });
        }

上面应该创建一个注入依赖项的 OrdersListViewModel 实例。

运行 iOS 应用程序不会在构造函数中注入依赖项,因此它始终属于服务位置解析。

我绝对可以不用 DI 实现可选的构造函数模式,因为单元测试仍然很容易,但我想知道为什么它不起作用。

我在这个链接中找到https://reactiveui.readthedocs.org/en/latest/dependency-injection/splat/,最后一段说。

指南的高级部分描述了如何连接第三方 依赖注入框架。然而,读者高度 鼓励放弃这个想法并使用默认解析器。

可是,找不到进阶版块,还有为什么鼓励放弃这个想法?我仍然可以拥有世界上最好的,对吧?

目前还不确定这是不是 Ninject 问题,或者我不知道将它与 ReactiveUI 连接的步骤,尽管我之前没有遇到过 Ninject DI 问题。

【问题讨论】:

    标签: dependency-injection xamarin ninject reactiveui


    【解决方案1】:

    我很难确切地说出您的解决方案出了什么问题,但我想我可以为您提供一些关于将 DI 框架连接到 RxUI 的指导。

    您可以找到good example using Autofac on Github。这一切都归结为将您选择的 DI 包装在实现 IMutableDependencyResolver 的类中(请参阅 example),然后将其分配给 Locator.Current 属性。

    关于为什么你最好使用 Splat,there is a great answer on SO by the creator of RxUI and Splat himself 关于这个话题。基本上,

    我通常认为很多关于 IoC/DI 的建议在“跨平台移动应用程序”领域都非常糟糕,因为您必须记住,他们的很多想法都是为网络应用程序编写的,而不是移动应用程序或移动应用程序。桌面应用程序。

    例如,绝大多数流行的 IoC 容器只关心暖缓存上的解析速度,而基本上完全不考虑内存使用或启动时间——这对于服务器应用程序来说是 100% 没问题的,因为这些事情并不重要;但对于移动应用程序?启动时间很长。

    Splat 的 Service Location 解决了 RxUI 的许多问题:

    1. Service Location 速度很快,而且几乎没有设置开销。
    2. 它封装了几种不同的常见对象生命周期模型(即'create new every time'、'singleton'、'lazy'),只是通过不同的方式编写 Func
    3. 它对 Mono 链接器友好(通常)
    4. 服务位置允许我们在特定于平台的代码中注册类型,但在 PCL 代码中使用它们。

    【讨论】:

    • 是的,我已经看过 Paul 关于服务位置的回答,但在链依赖方面,它真的优于使用 Autofac 或 Ninject 等 DI 容器吗?我的意思是,我可以在我的所有虚拟机和服务中使用 Splat 构造函数到构造函数,但是再次......感谢替换服务定位器的信息。不确定我是否真的需要这个,我只想使用 Ninject 在我的 VM 构造函数中注入依赖项,它不起作用有点奇怪。我想我只能坚持使用 Splat。
    • 标记为已解决,它回答了如何连接第三方 DI 容器作为 ReactiveUI 默认解析器的问题。我将进一步调查 Ninject 以查看它是否与 ReactiveUI 相关并提出一个新问题。
    猜你喜欢
    • 1970-01-01
    • 2014-09-06
    • 2010-09-14
    • 1970-01-01
    • 2016-08-19
    • 2017-03-05
    • 1970-01-01
    • 2015-02-12
    • 1970-01-01
    相关资源
    最近更新 更多