使用初始化时在 shell 视图模型的模块中注册的服务(WPF、Prism)

Using the services that registered in module at the shell viewmodel at the initialize time (WPF, Prism)

我正在尝试使用 Prism 来构建我的应用程序,我遇到了一个异常,但我不知道如何解决这个问题。

在 app.xaml.cs 文件中,我覆盖了 CreateShell() 方法来创建用作占位符的 shell。

public partial class App
{
    protected override Window CreateShell()
    {
        return Container.Resolve<MainView>();
    }

    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
        containerRegistry.RegisterForNavigation<MainView, MainViewModel>();
    }

    protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
    {
        moduleCatalog.AddModule<ServiceModule>();
    }
}

然后在服务模块中,我在容器中注册了日志记录服务。

    public class ServiceModule : IModule
    {
        public void OnInitialized(IContainerProvider containerProvider)
        {

        }

        public void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.RegisterSingleton<ILoggingService, LoggingService>();
        }
    }

并且我想在MainViewModelclass中使用Logger,所以我在MainViewModel构造函数中注入了ILoggingService服务。

    public class MainViewModel : BindableBase
    {
        private readonly ILoggingService _logger;

        public MainViewModel(ILoggingService logger)
        {
            _logger = logger;
        }
    }

但事情就是这样,当我尝试 运行 这段代码时,他们抛出异常,因为 ILoggingService 的 public 构造函数未确定。 我看到了初始化应用程序的棱镜项目代码 class 他们在 PrismApplicationBase class 中定义的内容,我终于得到了一个简单的问题。

        public virtual void Initialize()
        {
            // ...... Initialize somthing else.......

            var shell = CreateShell();
            if (shell != null)
            {
                RegionManager.SetRegionManager(shell, _containerExtension.Resolve<IRegionManager>());
                RegionManager.UpdateRegions();
                InitializeShell(shell);
            }

            InitializeModules();
        }

在调用 CreateShell() 时,模块尚未初始化。

第一时间怀疑这个套路不对, 但我在 github 上发现了一条评论,它解释了为什么这个过程对代码所有者来说是正确的。 See on this

If CreateShell was last then you would not be able to inject views from within your modules, which would be a massive break and limitation. (brianlagunas)

根据 image 在 prism 文档中,模块可以作为服务使用。所以我相信这不是棱镜开发者不推荐的模式。

问题来了, 如果我想在占位符视图模型中使用我的服务(ILoggingService),我该怎么办? (MainViewModel)

What should I do if I want to use my service (ILoggingService) in the shell view model? (MainViewModel)

您必须从引导程序 ConfigureContainer 中注册它。或者你的PrismApplicationchildclass.

各自的方法