使用初始化时在 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>();
}
}
并且我想在MainViewModel
class中使用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
中注册它。或者你的PrismApplication
childclass.
各自的方法
我正在尝试使用 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>();
}
}
并且我想在MainViewModel
class中使用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
中注册它。或者你的PrismApplication
childclass.