我正在使用Prism Library WPF样本 here (具体来说, 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>();
}
}
答案 0 :(得分:5)
而不是将具体的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
接口注册为singleton)。所以你的模块,你的PersonListViewModel
等都有不同的区域管理器实例,所以导航中断。