Dependency injection 将第三方依赖项注入框架与ReactiveUI连接

Dependency injection 将第三方依赖项注入框架与ReactiveUI连接,dependency-injection,xamarin,ninject,reactiveui,Dependency Injection,Xamarin,Ninject,Reactiveui,我正在检查ReactiveUI MVVM框架。我真的很喜欢Rx的概念,并希望开始使用和学习它为我的下一个项目 但是,我发现在尝试将其与Ninject或第三方DI容器一起使用时缺少文档 我通常在平台应用层中设置Ninject并在那里注册依赖项。然后使用它通过构造函数注入依赖项,或者在需要时通过服务位置解析依赖项 我发现这种可选构造函数依赖关系模式非常好,使构造函数中的依赖关系成为可选的,如果使用服务位置解析为null,则在单元测试时注入模拟依赖关系 假设你有这个构造函数 public Orders

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

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

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

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

假设你有这个构造函数

public OrdersListViewModel(IWebOrdersRepository<Order> webOrdersRepository = null)
        {
            _webOrdersRepository = webOrdersRepository ?? Locator.Current.GetService<IWebOrdersRepository<Order>>();
        }
我在UIViewController ViewDidLoad方法中创建OrdersListViewModel

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

            ViewModel = await BlobCache.LocalMachine.GetOrCreateObject(OrdersListViewModel.Key, () => {
                return NinjectKernel.Get<OrdersListViewModel>();
            });
        }
public override async void ViewDidLoad()
{
base.ViewDidLoad();
ViewModel=wait BlobCache.LocalMachine.GetOrCreateObject(OrdersListViewModel.Key,()=>{
返回NinjectKernel.Get();
});
}
上面应该创建一个注入依赖项的OrdersListViewModel实例

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

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

我发现在这个链接中,最后一段说

本指南的高级部分介绍了如何连接第三方网络 依赖注入框架。然而,读者对此高度关注 鼓励您放弃这个想法,使用默认的解析器

但是,找不到高级部分,为什么鼓励它放弃这个想法?我还可以吃世界上最好的,对吗


目前,我还不太确定这是Ninject问题还是我不知道如何将其与ReactiveUI连接起来,尽管我以前在Ninject DI方面没有问题。

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

你可以找到一份工作。这一切归结为将您选择的DI封装在实现
IMutableDependencyResolver
(请参阅)的类中,然后将其分配给
Locator.Current
属性

至于为什么你最好使用Splat,关于这个话题。基本上

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

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

Splat的服务位置为RxUI解决了许多问题:

  • 服务位置很快,几乎不需要设置开销
  • 它封装了几种不同的通用对象生存期模型(即“每次创建新对象”、“单例”、“惰性”),只需以不同的方式编写Func即可
  • 它对单链接器友好(通常)
  • 服务位置允许我们在特定于平台的代码中注册类型,但在PCL代码中使用它们

  • 是的,我已经看过Paul关于服务位置的回答,但是当涉及到链依赖时,它真的比使用Autofac或Ninject这样的DI容器好吗?我的意思是,我可以在我所有的虚拟机和服务中使用Splat构造函数来构造,但是。。。。感谢您提供更换服务定位器的信息。不确定我是否真的需要它,我只想使用Ninject在我的VM构造函数中注入依赖项,奇怪的是它不起作用。我想我必须坚持使用Splat。标记为已解决,它回答了如何连接第三方DI容器作为ReactiveUI默认解决程序的问题。我将进一步调查Ninject,看看它是否与ReactiveUI相关,并提出一个新问题。
    NinjectKernel.Initialize(new NinjectConfiguration());
    
    public override async void ViewDidLoad()
            {
                base.ViewDidLoad();
    
                ViewModel = await BlobCache.LocalMachine.GetOrCreateObject(OrdersListViewModel.Key, () => {
                    return NinjectKernel.Get<OrdersListViewModel>();
                });
            }