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

标签 c# wpf prism prism-6 dryioc

我正在使用 Prism 库 WPF 示例 here (具体来说, this one )。

我正在尝试将示例的 Bootstrap 从使用 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>();
    }
}

最佳答案

不是将具体的 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 容器中注册(仅接口(interface))。但是当您尝试解析未注册的类型时,DryIoc 不会抛出异常,而是会尝试创建此类型的实例(并解析其依赖项(如果有))。

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

关于c# - 如何使用 DryIoc 而不是 Unity 在 Prism 中配置模块目录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49580430/

相关文章:

c# - Label Xamarin.Forms 中的可点击 HTML 超链接

c# - 中止请求 wp7

c# - IsMouseCaptured 变为 False

c# - Prism 5 模块化 : how to add RegionName in DataTemplate of TabControl in ItemsControl

wpf - 登录窗口到 Prism 中的主窗口 (WPF)

c# - 从 Google 中的客户端电子邮件和私钥(服务帐户)获取 token

c# - 系统中存在的 dot Net Web 浏览器对象和 Internet Explorer 之间有什么关系?

wpf - WPF MediaKit音频问题

WPF 绑定(bind) : Waiting for ItemsSource

c# - 自定义控件可绑定(bind)属性中的值未更新 - Xamarin forms/Prism