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

The viewmodel looks like that (excerpt)


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

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.ConstructorSelectorPolicyBase
1.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.

1
  • Can you show the code for your PersonModule? Commented Sep 8, 2010 at 15:31

1 Answer 1

5

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

Container.RegisterType<EntityContext >("Context", new InjectionConstructor(...))
Sign up to request clarification or add additional context in comments.

2 Comments

I tried it, but the constructors should be disambiguate, because the auto-generated designer file contains a class EntityContext which inherits from ObjectContext. There three constructors with zero and one parameter - EntityContext(), EntityContext(string connectionString) , EntityContext(EntityConnection connection). Hence it should also work with just Container.RegisterType<EntityContext >("Context"), shouldn't it?
No, it doesn't, because the container tries to use to constructor with the maximum number of the parameters. If you have two constructors with 1 parameter, it can't figure out how to build it. You have to disambiguate (either configuring the container as in my answer or with InjectionConstructor attribute)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.