我真的只是从 MVVM、IoC 和依赖注入开始,我遇到了一个我不知道如何解决的绊脚石,但我明白它为什么会发生。
我将 Castle Windsor 用于 DI 和 IoC 功能,并将 MVVM Light 作为我在 WPF 应用程序中的 MVVM 框架。使用本教程,我设法让 Castle Windsor 创建一个MainPageViewModel
注入IGroupRepository
构造函数的函数。我已经在温莎城堡注册了一个模拟实现。
以下是MainPageViewModel
该类中除构造函数之外的唯一其他代码。
public ObservableCollection<GroupViewModel> Groups
{
get
{
var groupVms = new ObservableCollection<GroupViewModel>();
IEnumerable<Group> groups = _repository.GetAllGroups();
foreach (Group g in groups)
{
var vm = new GroupViewModel(g);
groupVms.Add(vm);
}
return groupVms;
}
}
目的是为存储库中的每个组创建一个视图模型。但是,这样做会导致 Castle Windsor 给出以下异常:
无法创建组件“Planner.ViewModel.GroupViewModel”,因为它需要满足依赖关系。'Planner.ViewModel.GroupViewModel' 正在等待以下依赖项:
- 未注册的服务“Planner.Models.Group”。
我理解这个例外 - Castle Windsor 负责构建我的视图模型,但它无法处理我的实体。
我做了很多谷歌搜索,但发现这个问题的答案或建议很少,这让我认为我所做的事情是错误的。 这个 Stack Overflow 问题有两个答案表明在视图模型上有一个实体是可以的,但我开始怀疑这是否属实。其他问题,例如这个问题表明实体不应该靠近视图模型。
解决此问题的正确方法是什么?
更新:根据要求,这是异常的堆栈跟踪:
at Castle.MicroKernel.Handlers.DefaultHandler.AssertNotWaitingForDependency()
at Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, Boolean requiresDecommission, Boolean instanceRequired, Burden& burden)
at Castle.MicroKernel.Handlers.DefaultHandler.Resolve(CreationContext context, Boolean instanceRequired)
at Castle.MicroKernel.Handlers.AbstractHandler.Resolve(CreationContext context)
at Castle.MicroKernel.DefaultKernel.ResolveComponent(IHandler handler, Type service, IDictionary additionalArguments, IReleasePolicy policy)
at Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(Type service, IDictionary arguments, IReleasePolicy policy)
at Castle.MicroKernel.DefaultKernel.Resolve(Type service, IDictionary arguments)
at Castle.Windsor.WindsorContainer.Resolve(Type service)
at Planner.ViewModel.ViewModelResolver.Resolve(String viewModelName) in D:\Planner\Planner\Planner\ViewModel\ViewModelResolver.cs:line 27
at Planner.ViewModel.ViewModelLocator.get_Item(String viewModelName) in D:\Planner\Planner\Planner\ViewModel\ViewModelLocator.cs:line 21
我认为这是正确的行为,因为下面的代码(我相信)拦截了对视图模型构造函数的任何调用并在适当时注入它们。
public class ViewModelResolver : IViewModelResolver
{
private IWindsorContainer _container;
public object Resolve(string viewModelName)
{
if (_container == null)
{
_container = new WindsorContainer();
_container.Install(new WindsorViewsInstaller());
_container.Install(new WindsorRepositoriesInstaller());
}
var viewModelType =
GetType()
.Assembly
.GetTypes()
.Where(t => t.Name.Equals(viewModelName))
.FirstOrDefault();
return _container.Resolve(viewModelType);
}
}
更新 2:我认为这回答了 Ritch 的问题:
public class ViewModelLocator : DynamicObject
{
public IViewModelResolver Resolver { get; set; }
public ViewModelLocator()
{
Resolver = new ViewModelResolver();
}
public object this[string viewModelName]
{
get
{
return Resolver.Resolve(viewModelName);
}
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = this[binder.Name];
return true;
}
}
我想我现在对这一点有了更多的了解。问题实际上不在于我发布的原始代码。问题实际上是在设置温莎时发生的,不是吗?不过,我仍然不确定如何解决该问题。