开发者

Constructor Injection of an ObjectContext using Unity/Prism/MVVM

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

The viewmodel looks like that (excerpt)


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

    public P开发者_如何学JAVAersonViewModel(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;
        }
    }      
}

I'm not sure if my approach is working in principle but for the sake of saving changes to the database I need my context in knowledge of changes made to it. Right now it is obviously not working bacause an ModuleInitializeException occurs. Stacktrace:

An exception occurred while initializing module 'PersonModule'.

- The exception message was: An exception has occurred while trying to add a view to region 'PersonData'.

- The most likely causing exception was was: 'System.InvalidOperationException: The type EntityContext has multiple constructors of length 1. Unable to disambiguate.

bei Microsoft.Practices.ObjectBuilder2.ConstructorSelectorPolicyBase1.FindLongestConstructor(Type typeToConstruct)

bei Microsoft.Practices.ObjectBuilder2.ConstructorSelectorPolicyBase1.SelectConstructor(IBuilderContext context)

bei Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.PreBuildUp(IBuilderContext context)

bei Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)'.

But also check the InnerExceptions for more detail or call .GetRootException(). - The Assembly that the module was trying to be loaded from was:App, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

Check the InnerException property of the exception for more information. If the exception occurred while creating an object in a DI container, you can exception.GetRootException() to help locate the root cause of the problem.

If there are other solutions for that problem I'm open-minded to it, but I want to use the basic structure presented more or less.

Thanks in advance.


You have to configure the container to disambiguate the construction of EntityContext:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜