我正在使用棱镜库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));
    }
}


但是,当我尝试运行新代码时,出现以下异常:

c# - 如何使用DryIoc而不是Unity在Prism中配置模块目录?-LMLPHP

内部异常说:

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在多个级别上都被打破。这是因为ContainerRegionManager作为具体类型均未在DryIoc容器中注册(仅在接口中)。但是,当您尝试解析未注册的类型时,DryIoc而不是引发异常,将尝试创建该类型的实例(并解决其依赖项(如果有))。

使用Container创建失败。使用RegionManager可以成功,但是问题是每个解决方案都会创建RegionManager的新实例(而IRegionManager接口被注册为单例)。因此,您的模块,您的PersonListViewModel等都具有不同的区域管理器实例,因此导航中断。

10-08 14:07