繁体   English   中英

Prism 2.1将模块注入ViewModel

[英]Prism 2.1 Injecting Modules into ViewModel

我一直在尝试将ModuleCatalog中的模块注入我的Shell的ViewModel,但我运气不好......

我正在我的Bootstrapper中创建ModuleCatalog,我的模块从其Initializer进入屏幕没有问题。 但是,我希望能够将我的模块列表绑定到一个带有DataTemplate的容器,从而允许它们从菜单中启动!

这是我的Boostrapper文件,随着时间的推移,我将添加更多模块,但就目前而言,它只包含了我设计的“ProductAModule”:

public class Bootstrapper : UnityBootstrapper
{
    protected override void ConfigureContainer()
    {
        Container.RegisterType<IProductModule>();

        base.ConfigureContainer();
    }

    protected override IModuleCatalog GetModuleCatalog()
    {
        return new ModuleCatalog()
            .AddModule(typeof(ProductAModule));
    }

    protected override DependencyObject CreateShell()
    {
        var view = Container.Resolve<ShellView>();
        var viewModel = Container.Resolve<ShellViewModel>();
        view.DataContext = viewModel;
        view.Show();

        return view;
    }
}

接下来,这是我的Shell的ViewModel:

public class ShellViewModel : ViewModelBase
{
    public List<IProductModule> Modules { get; set; }

    public ShellViewModel(List<IProductModule> modules)
    {
        modules.Sort((a, b) => a.Name.CompareTo(b));
        Modules = modules;
    }
}

正如您所看到的,我正在尝试注入一个IProductModule列表(ProductAModule继承了它的一些属性和方法),以便它可以绑定到我的Shell的View。 是否有一些非常简单的我缺少或者不能使用Unity IoC? (我已经看到它完成了StructureMap对Prism的扩展)

还有一件事......当运行应用程序时,在Bootstrapper中的Container正在解析ShellViewModel时,我收到以下异常:

依赖项的解析失败,type =“PrismBasic.Shell.ViewModels.ShellViewModel”,name =“”。 异常消息是:当前构建操作(构建密钥构建密钥[PrismBasic.Shell.ViewModels.ShellViewModel,null])失败:尝试调用构造函数PrismBasic.Shell.ViewModels.ShellViewModel(System.Collections)时无法解析参数模块.Generic.List`1 [[PrismBasic.ModuleBase.IProductModule,PrismBasic.ModuleBase,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null]] modules)。 (策略类型BuildPlanStrategy,索引3)

无论如何,简单吧......看起来很困惑......

任何帮助将不胜感激!

我想你可能只是这样做:

public class Bootstrapper : UnityBootstrapper
{
    protected override void ConfigureContainer()
    {
        Container.RegisterType<IProductModule>();

        base.ConfigureContainer();
    }

    private static ObservableCollection<IProductModule> _productModules = new Obser...();
    public static ObservableCollection<IProductModule> ProductModules
    { 
         get { return _productModules; } 
    }
    protected override IModuleCatalog GetModuleCatalog()
    {
        var modCatalog = new ModuleCatalog()
            .AddModule(typeof(ProductAModule));
        //TODO: add all modules to ProductModules collection

        return modCatalog;
    }

   ...
}

然后你会有一个静态属性,任何东西都可以直接绑定,或者可以从你的ViewModel中使用。


以下是如何获取已在模块目录中注册的模块名称列表。

public class MyViewModel : ViewModel
{

      public ObservableCollection<string> ModuleNames { ... }
      public MyViewModel(IModuleCatalog catalog)
      {
           ModuleNames = new ObservableCollection<string>(catalog.Modules.Select(mod => mod.ModuleName));
      }
}

这就是它。 IModuleCatalog和IModuleManager是容器中设置的唯一内容,供您根据模块进行访问。 正如我所说, 你不会获得任何实例数据,因为这些模块(希望)尚未创建 您只能访问类型数据。

希望这可以帮助。

我想你误解了模块的用途。 这些模块只是您希望使用的视图和服务的容器。 另一方面,shell应该只包含应用程序的主要布局。

我认为您应该做的是在shell中定义一个区域,然后在该区域中注册视图(在您的情况下是按钮)。

您希望如何根据模块部署视图和服务与您正在寻找的模块化级别更相关,即您是否希望能够独立于ModuleB的视图和服务部署ModuleA的视图和服务等等。 在您的情况下,将所有内容注册到一个模块中就足够了。

花一些时间来阅读文档提供的示例,它们非常好。

您的示例抛出示例的原因是因为您的ShellViewModel依赖于List并且该类型未在Unity中注册。 此外,您正在使用Unity注册IProductModule,这是没有意义的,因为无法构造接口。

我想我今天遇到了类似的问题,事实证明PRISM在初始化模块之前创建了shell,因此你不能将模块中的任何服务注入shell本身。

尝试创建另一个依赖于所有其他模块并实现所需功能的模块,然后将其添加到shell中的某个区域以显示您的服务列表。 不幸的是,我还没有机会尝试它,但这是我计划实施的解决方案。

作为旁注,我认为您需要使用属性标记属性以使用属性注入,但我可能是错误的(自从我直接使用Unity以来已经有一段时间了)。


编辑:您需要将DependencyAttribute应用于属性以在Unity中使用setter注入; 你可以 在这里阅读它。

var modules = new IProductModule[]
{
    Container.Resolve<ProductAModule>()
    //Add more modules here...
};
Container.RegisterInstance<IProductModule[]>(modules);

而已! 使用此代码,我可以将我的模块注入到ShellViewModel中,并将每个模块显示为我的应用程序中的按钮!

这个简单的解决方案! 来自CompositeWPF Discussion小组的好人。 我推荐他们没有保留^ _ ^

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM