我正在使用棱镜库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>();
}
}
最佳答案
无需将具体的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
等都具有不同的区域管理器实例,因此导航中断。