【问题标题】:Replace Splat in ReactiveUI with Simple Injector用 Simple Injector 替换 ReactiveUI 中的 Splat
【发布时间】:2017-04-02 20:02:35
【问题描述】:

我正在尝试用 Simple Injector 替换 ReactiveUI 中的 Splat。我正在使用 SI 的包插件。这是我的配置:

    public void RegisterServices(Container container)
    {
        // I also registered other stuff in here with container.Register()
        // but this code has been removed in the question.
        Locator.Current = new FuncDependencyResolver((service, contract) =>
        {
            if (contract != null) return container.GetAllInstances(service);
            var items = container.GetAllInstances(service);
            var list = items.ToList();
            return list;
        },
        (factory, service, contract) =>
        {
            container.AppendToCollection(service, Lifestyle.Transient.CreateRegistration(service,   container));
        });
    }

这是我在视图的构造函数中放入的内容:

// Bind code inside View.
this.Bind(ViewModel, vm => vm.OutputDirectory, v => v.comboBoxAdvOutputFolder.Text);

只要我在项目中使用 Bind,就会引发异常:“Project1.Windows.dll 中发生了 'System.TypeInitializationException' 类型的异常,但未在用户代码中处理。

附加信息:“ReactiveUI.BindingMixins”的类型初始化程序引发了异常。”

当我以这种方式替换 Locator.Current 时,看起来 ViewModel 仍然为空。

编辑:我认为我在代码中犯了一个小错误。这是修改后的版本:

        Locator.Current = new FuncDependencyResolver((service, contract) =>
        {
            return container.GetAllInstances(service);
        },
        (factory, service, contract) =>
        {
            container.AppendToCollection(service, Lifestyle.Transient.CreateRegistration(service, factory, container));
        });

编辑: 看起来问题是调用 GetAllInstances 后无法修改 Simple Injector 的容器,我猜 FuncDependencyResolver 会这样做。有解决办法吗?

【问题讨论】:

    标签: c# inversion-of-control simple-injector reactiveui splat


    【解决方案1】:

    我无法用 SimpleInjector 完全替换 Splat。我必须保留 IMutableDependencyResolver 并在自定义 FuncDependencyResolver 中引用它。 Locator.Current 基本上首先遵循 Splat,然后是 SimpleInjector。这很好用,因为 RxUI 使用 Locator.Current。我所有的课程都只在 SimpleInjector 中注册,不使用 Locator.Current。

    SplatResolver = Locator.CurrentMutable;
    var customResolver = new FuncDependencyResolver((service, contract) =>
    {
        IEnumerable<Object> services = null;
        services = SplatResolver.GetServices(service, contract);
        if (services == null || services.Count() == 0)
        {
            var svc = containerSI.GetInstance(service);
            if (svc != null)
            {
                services = new Object[] { svc };
            }
        }
        if (services == null || services.Count() == 0)
        {
            services = containerSI.GetAllInstances(service); // only applies services registered with .RegisterCollection()
        }
        return services;
    }, (factory, service, contract) =>
    {
        SplatResolver.Register(factory, service, contract);
    
        try
        {
            containerSI.Register(service, factory);
        }
        catch (Exception exc)
        {
            // certain services are registered multiple times by RxUI.  For now, ignore them.
            //ICreatesObservableForProperty
            Console.WriteLine(exc.ToString());
        }
    });
    
    Locator.Current = customResolver;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-21
      相关资源
      最近更新 更多