【问题标题】:Constructor Injection of an ObjectContext using Unity/Prism/MVVM使用 Unity/Prism/MVVM 的 ObjectContext 的构造函数注入
【发布时间】:2010-09-08 15:15:46
【问题描述】:

我使用带有 MVVM 模式和 Prism 的 WPF 开发了一个应用程序。视图被添加到 ModuleCatalog 中,并且视图模型被注册到一个统一容器中。为此,我使用的是负责创建外壳、配置统一容器和模块目录的引导程序。
现在的问题是,如何将我的 EntityContext 注入到几个视图模型中。
首先是引导程序:

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

模块:


    public class PersonModule : IModule
    {
        private readonly IRegionManager regionManager;

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

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

}

视图代码隐藏:


    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)
bei Microsoft.Practices.ObjectBuilder2.ConstructorSelectorPolicyBase
1.SelectConstructor(IBuilderContext 上下文)
bei Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.PreBuildUp(IBuilderContext context)
bei Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)'。
但也请检查 InnerExceptions 以了解更多详细信息或调用 .GetRootException()。 - 试图从中加载模块的程序集是:App,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null
检查异常的 InnerException 属性以获取更多信息。如果在 DI 容器中创建对象时发生异常,您可以通过 exception.GetRootException() 来帮助定位问题的根本原因。

如果该问题有其他解决方案,我对此持开放态度,但我想或多或少地使用所介绍的基本结构。
提前致谢。

【问题讨论】:

  • 你能展示一下你的 PersonModule 的代码吗?

标签: c# mvvm dependency-injection entity-framework-4 unity-container


【解决方案1】:

你必须配置容器来消除EntityContext的构造:

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

【讨论】:

  • 我试过了,但构造函数应该是明确的,因为自动生成的设计器文件包含一个继承自 ObjectContext 的类 EntityContext。有 0 个参数和 1 个参数的三个构造函数 - EntityContext()、EntityContext(string connectionString)、EntityContext(EntityConnection connection)。因此它也应该只与 Container.RegisterType("Context") 一起使用,不是吗?
  • 不,它没有,因为容器尝试使用具有最大参数数量的构造函数。如果您有两个带有 1 个参数的构造函数,它无法弄清楚如何构建它。您必须消除歧义(按照我的答案配置容器或使用 InjectionConstructor 属性)
猜你喜欢
  • 2012-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多