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

时间:2018-03-30 19:39:34

标签: c# wpf prism prism-6 dryioc

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

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

enter image description here

内部例外说:

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>();
    }
}

1 个答案:

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

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