如何使用 DryIoc 而不是 Unity 在 Prism 中配置模块目录?
How do I Configure the Module Catalog in Prism using DryIoc instead of Unity?
我正在使用 Prism 库 WPF 示例 here (specifically, this one).
我正在尝试将示例的引导程序从使用 Unity 容器转换为 DryIoc。原始代码如下所示:
class Bootstrapper : UnityBootstrapper
{
protected override DependencyObject CreateShell()
{
return Container.Resolve<MainWindow>();
}
protected override void InitializeShell()
{
Application.Current.MainWindow.Show();
}
protected override void ConfigureModuleCatalog()
{
var catalog = (ModuleCatalog)ModuleCatalog;
catalog.AddModule(typeof(ModuleAModule));
}
}
我的新代码如下所示:
class Bootstrapper : DryIocBootstrapper
{
protected override DependencyObject CreateShell()
{
return Container.Resolve(typeof(MainWindow), true) as DependencyObject;
}
protected override void InitializeShell()
{
Application.Current.MainWindow.Show();
}
protected override void ConfigureModuleCatalog()
{
var catalog = (ModuleCatalog)ModuleCatalog;
catalog.AddModule(typeof(ModuleAModule));
}
}
但是当我尝试 运行 新代码时,出现以下异常:
内部异常说:
Activation error occurred while trying to get instance of type ModuleAModule, key ""
那个异常的内部异常说:
Unable to get constructor of DryIoc.Rules using provided constructor selector when resolving DryIoc.Rules {ReturnDefault} as parameter "rules"
in DryIoc.Container as parameter "container"
in ModuleA.ModuleAModule.
ModuleAModule 的代码:
public class ModuleAModule : IModule
{
IRegionManager _regionManager;
Container _container;
public ModuleAModule(RegionManager regionManager, Container container)
{
_regionManager = regionManager;
_container = container;
}
public void Initialize()
{
_regionManager.RegisterViewWithRegion("ContentRegion", typeof(PersonList));
_container.RegisterTypeForNavigation<PersonDetail>();
}
}
而不是将具体的 Container
类型传递给模块构造函数 - 您需要传递 IContainer
:
public ModuleAModule(RegionManager regionManager, IContainer container)
{
_regionManager = regionManager;
_container = container;
}
这将解决您的问题,但导航将不起作用。要修复导航 - 您需要对 RegionManager
执行相同的操作,即:传递 IRegionManager
而不是具体类型:
public ModuleAModule(IRegionManager regionManager, IContainer container)
不仅在模块本身,而且在其他地方,例如在PersonListViewModel
:
public PersonListViewModel(IRegionManager regionManager)
传递具体实现通常不是一个好的做法,这里它在 DryIoc 的多个级别上中断。这是因为 Container
和 RegionManager
作为具体类型都没有在 DryIoc 容器中注册(仅接口)。但是,当您尝试解析未注册的类型时,DryIoc 不会抛出异常,而是会尝试创建此类型的实例(并解析其依赖项(如果有))。
在 Container
中,创建失败。使用 RegionManager
它成功了,但问题是每个解决方案都会创建 RegionManager
的新实例(而 IRegionManager
接口被注册为单例)。所以你的模块,你的 PersonListViewModel
等都有不同的区域管理器实例,所以导航中断。
我正在使用 Prism 库 WPF 示例 here (specifically, this one).
我正在尝试将示例的引导程序从使用 Unity 容器转换为 DryIoc。原始代码如下所示:
class Bootstrapper : UnityBootstrapper
{
protected override DependencyObject CreateShell()
{
return Container.Resolve<MainWindow>();
}
protected override void InitializeShell()
{
Application.Current.MainWindow.Show();
}
protected override void ConfigureModuleCatalog()
{
var catalog = (ModuleCatalog)ModuleCatalog;
catalog.AddModule(typeof(ModuleAModule));
}
}
我的新代码如下所示:
class Bootstrapper : DryIocBootstrapper
{
protected override DependencyObject CreateShell()
{
return Container.Resolve(typeof(MainWindow), true) as DependencyObject;
}
protected override void InitializeShell()
{
Application.Current.MainWindow.Show();
}
protected override void ConfigureModuleCatalog()
{
var catalog = (ModuleCatalog)ModuleCatalog;
catalog.AddModule(typeof(ModuleAModule));
}
}
但是当我尝试 运行 新代码时,出现以下异常:
内部异常说:
Activation error occurred while trying to get instance of type ModuleAModule, key ""
那个异常的内部异常说:
Unable to get constructor of DryIoc.Rules using provided constructor selector when resolving DryIoc.Rules {ReturnDefault} as parameter "rules"
in DryIoc.Container as parameter "container"
in ModuleA.ModuleAModule.
ModuleAModule 的代码:
public class ModuleAModule : IModule
{
IRegionManager _regionManager;
Container _container;
public ModuleAModule(RegionManager regionManager, Container container)
{
_regionManager = regionManager;
_container = container;
}
public void Initialize()
{
_regionManager.RegisterViewWithRegion("ContentRegion", typeof(PersonList));
_container.RegisterTypeForNavigation<PersonDetail>();
}
}
而不是将具体的 Container
类型传递给模块构造函数 - 您需要传递 IContainer
:
public ModuleAModule(RegionManager regionManager, IContainer container)
{
_regionManager = regionManager;
_container = container;
}
这将解决您的问题,但导航将不起作用。要修复导航 - 您需要对 RegionManager
执行相同的操作,即:传递 IRegionManager
而不是具体类型:
public ModuleAModule(IRegionManager regionManager, IContainer container)
不仅在模块本身,而且在其他地方,例如在PersonListViewModel
:
public PersonListViewModel(IRegionManager regionManager)
传递具体实现通常不是一个好的做法,这里它在 DryIoc 的多个级别上中断。这是因为 Container
和 RegionManager
作为具体类型都没有在 DryIoc 容器中注册(仅接口)。但是,当您尝试解析未注册的类型时,DryIoc 不会抛出异常,而是会尝试创建此类型的实例(并解析其依赖项(如果有))。
在 Container
中,创建失败。使用 RegionManager
它成功了,但问题是每个解决方案都会创建 RegionManager
的新实例(而 IRegionManager
接口被注册为单例)。所以你的模块,你的 PersonListViewModel
等都有不同的区域管理器实例,所以导航中断。