使用Unity/Prism/MVVM进行构造函数注入ObjectContext对象

3

I develop an application using WPF with MVVM pattern and Prism. The views are added to the ModuleCatalog and the viewmodels are registered to a unity container. For that I'm using a Bootstrapper which is responsible creating the shell, configuring the unity container and the module catalog.
The question is now, how injecting my EntityContext to the several viewmodels.
First the Bootstrapper:

 
public class Bootstrapper : UnityBootstrapper
    {
        protected override DependencyObject CreateShell()
        {
            Shell shell = Container.Resolve();
            shell.Show();
            return shell;
        }

    protected override void ConfigureContainer()
    {
        base.ConfigureContainer();
        Container.RegisterType<EntityContext >("Context");
        Container.RegisterType<PersonViewModel>(new InjectionConstructor(
            new ResolvedParameter<EntityContext >("Context")));
    }

    protected override IModuleCatalog GetModuleCatalog()
    {
        ModuleCatalog catalog = new ModuleCatalog();
        catalog.AddModule(typeof(PersonModule));
        return catalog;
    }

视图模型长这样(摘录)


public class PersonViewModel : ViewModelBase, IDataErrorInfo
    {
        private Person _person;
        private PersonRepository _repository;
        readonly EntityContext _context;

    public PersonViewModel(EntityContext context)
    {
        _context = context;
        _person = new Person();
        _repository = new PersonRepository(context);
    }

The module:


    public class PersonModule : IModule
    {
        private readonly IRegionManager regionManager;

    public PersonModule(IRegionManager regionManager)
    {
        this.regionManager = regionManager;
    }

    public void Initialize()
    {
        regionManager.RegisterViewWithRegion("PersonData", typeof(PersonView));
    }

}

The view code-behind:


    public partial class PersonView : UserControl
    {
        private PersonViewModel _vm;

    public PersonView()
    {
        InitializeComponent();
    }

    [Dependency]
    public PersonViewModel VM
    {
        get
        {
            return this.DataContext as PersonViewModel;
        }
        set
        {
            _vm = value;
            this.DataContext = _vm;
        }
    }      
}

我不确定我的方法在原则上是否有效,但为了保存对数据库的更改,我需要了解对其所做更改的上下文。目前显然并未工作,因为出现了ModuleInitializeException。堆栈跟踪:
初始化模块'PersonModule'时发生异常。
- 异常消息是:尝试向区域'PersonData'添加视图时发生异常。
- 最有可能引起异常的是:'System.InvalidOperationException: 类型EntityContext具有多个长度为1的构造函数。无法消除歧义。
在Microsoft.Practices.ObjectBuilder2.ConstructorSelectorPolicyBase1.FindLongestConstructor(Type typeToConstruct)
在Microsoft.Practices.ObjectBuilder2.ConstructorSelectorPolicyBase
1.SelectConstructor(IBuilderContext context)
在Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.PreBuildUp(IBuilderContext context)
在Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)'中。
但也要检查InnerExceptions以获取更多详细信息或调用.GetRootException()。 - 模块尝试加载的程序集是:App,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null
若要获取更多信息,请检查异常的InnerException属性。如果异常发生在DI容器中创建对象时,您可以使用exception.GetRootException()来帮助定位问题的根本原因。
如果有其他解决该问题的方法,我很乐意尝试,但我想基本结构或多或少地使用它。
提前致谢。

你能展示一下你的PersonModule的代码吗? - BFree
1个回答

5

您需要配置容器以消除EntityContext的构建歧义:

Container.RegisterType<EntityContext >("Context", new InjectionConstructor(...))

我尝试过了,但构造函数应该是有歧义的,因为自动生成的设计文件包含一个从ObjectContext继承的类EntityContext。这里有三个构造函数,分别是零个和一个参数——EntityContext()、EntityContext(string connectionString)和EntityContext(EntityConnection connection)。 因此,只使用Container.RegisterType<EntityContext>("Context")也应该可以正常工作,不是吗? - Kai Krupka
不,它不会,因为容器尝试使用具有最大参数数量的构造函数。如果您有两个带有1个参数的构造函数,它无法确定如何构建它。您必须消除歧义(可以配置容器,如我的答案中所述,或使用InjectionConstructor属性)。 - onof

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接