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.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.You have to configure the container to disambiguate the construction of EntityContext:
Container.RegisterType<EntityContext >("Context", new InjectionConstructor(...))
精彩评论