ReactiveUi:使用 AutoFac 时如何替换默认的 IViewLocator?

ReactiveUi: How can I replace the default IViewLocator when using AutoFac?

高!

我正在尝试替换 WPF 中 ReactiveUi/Splat 的默认 IViewLocator。我正在使用 AutoFac 作为容器。

我的目标很简单:ReactiveUi/Splat 在为视图模型解析视图时应该使用我自定义的 IViewLocator 实现。

我确实阅读了所有可用的教程和 Whosebug 线程,但没有任何帮助。

目前我在引导程序时执行以下操作:(我尝试了很多不同的东西...)

namespace MDM
{
    public static class Bootstrapper
    {
        private static AutofacDependencyResolver? Locator;
        private static IContainer? Container;

        public static void Register()
        {
            Splat.Locator.CurrentMutable.InitializeSplat();
            Splat.Locator.CurrentMutable.InitializeReactiveUI();
            Splat.Locator.CurrentMutable.RegisterConstant<IViewLocator>(new ViewLocator());

            var builder = new ContainerBuilder();

            builder.RegisterType<MainWindowView>().As<IViewFor<MainWindowViewModel>>().SingleInstance();
            builder.RegisterType<EinstellungenView>().As<IViewFor<EinstellungenViewModel>>().SingleInstance();
            builder.RegisterType<MainWindowViewModel>().AsSelf().SingleInstance();
            builder.RegisterType<EinstellungenViewModel>().AsSelf().SingleInstance();

            Locator = builder.UseAutofacDependencyResolver();
            builder.RegisterInstance(Locator);

            Locator.InitializeReactiveUI();
            Splat.Locator.SetLocator(Locator);

            Container = builder.Build();

            Locator.SetLifetimeScope(Container);

        }

        public static T Resolve<T>() where T : class
        {
            return Container!.Resolve<T>();
        }

    }
}

在我的 IViewLocator 中调试以下代码行时从未命中:

public IViewFor? ResolveView<T>(T viewModel, string? contract = null)
{

}

所以我的问题是:引导时我需要做什么来告诉 ReactiveUi 使用我的 IViewLocator?

如果您决定放弃 Splat(ReactiveUI 使用的 IoC 容器)并使用 Autofac,那么您必须使用它,尤其是在 注册 服务时。
一旦(正确)注册了自定义 IoC 容器,就不应再使用 Splat 来解决任何依赖关系。尽管 Splat 会将服务请求重定向到 Autofac 容器,但我建议不要混合 API。

var containerBuilder = new ContainerBuilder();

// TODO::Register application's dependencies with Autofac

/* Configure Splat to use Autofac */
var autofacResolver = containerBuilder.UseAutofacDependencyResolver();
containerBuilder.RegisterInstance(autofacResolver);
autofacResolver.InitializeReactiveUI();

// AFTER configuring the IoC redirect, register the Splat service overrides
containerBuilder.RegisterType<ViewLocator>()
  .As<IViewLocator>()
  .SingleInstance();

var container = containerBuilder.Build(); 
autofacResolver.SetLifetimeScope(container);

不要使用服务定位器 anti-pattern。 IoC 容器不应分布在整个应用程序中。既不是注入参考也不是静态参考。
请改用 抽象工厂 模式。

因此,IViewLocator.ResolveView 必须使用工厂而不是您在 Bootstrapper.

中实现的静态 Resolve 方法