gpt4 book ai didi

c# - MVVM - 在 ViewModel 中使用实体

转载 作者:行者123 更新时间:2023-12-03 10:29:37 25 4
gpt4 key购买 nike

我真的只是从 MVVM、IoC 和依赖注入(inject)开始,我遇到了一个我不知道如何解决的绊脚石,但我明白它为什么会发生。

我将 CaSTLe Windsor 用于 DI 和 IoC 功能,并将 MVVM Light 作为我在 WPF 应用程序中的 MVVM 框架。使用 this tutorial我设法让温莎城堡创建了一个 MainPageViewModel有一个 IGroupRepository注入(inject)构造函数。我已经在温莎城堡注册了一个模拟实现。

以下是 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;
}
}

目的是为存储库中的每个组创建一个 View 模型。但是,这样做会导致 CaSTLe Windsor 给出以下异常:

Can't create component 'Planner.ViewModel.GroupViewModel' as it has dependencies to be satisfied. 'Planner.ViewModel.GroupViewModel' is waiting for the following dependencies:

  • Service 'Planner.Models.Group' which was not registered.


我理解这个异常(exception) - CaSTLe Windsor 负责构建我的 View 模型,但它无法处理我的实体。

我做了很多谷歌搜索,但发现这个问题的答案或建议很少,这让我认为我所做的事情是错误的。 This Stack Overflow question有两个答案表明在 View 模型上有一个实体是可以的,但我开始怀疑这是不是真的。其他问题, such as this one建议实体不应靠近 View 模型。

解决此问题的正确方法是什么?

更新:根据要求,这是异常的堆栈跟踪:
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

我认为这是正确的行为,因为下面的代码(我相信)拦截了对 View 模型构造函数的任何调用并在适当时注入(inject)它们。
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:我认为这回答了里奇的疑问:
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;
}
}

我想我现在对这一点有了更多的了解。问题实际上不在于我发布的原始代码。问题实际上是在设置温莎时发生的,不是吗?不过,我仍然不确定如何解决该问题。

最佳答案

楼盘GroupsMainPageViewModel创建了一堆不在容器中的虚拟机,但是您的堆栈跟踪是寻找绑定(bind)/创建 GroupViewModel 实例的定位器(为什么?我现在无法用您发布的代码来判断。)。

您对 GroupViewModel s 被创建以及容器正在做什么。您要么需要让 Windsor 通过工厂界面创建这些 Factory Interface Documentation或将它们完全从容器中移除并自行管理。基于直觉,我会倾向于工厂界面。

关于c# - MVVM - 在 ViewModel 中使用实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11548135/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com