这是一个设计决定,但由于我是这个项目的唯一开发人员,我没有其他人可以问.
我有一个MVVM项目,我有一个允许用户将人员添加到聚会预订的视图.有一个商业规则(和那个讨厌的"现实")说一个人不能被添加到同一个聚会的预订中.View调用RelayCommand来添加Person.
由于有添加Person的业务规则,我知道我需要调用Model.我的问题是:怎么样?
我可以在Model中调用一个方法,传递Person,如果返回true,我可以添加Person. - 或者 - 我可以订阅ViewModel的PropertyChanged,如果有人添加,请检查它们并在属性失败时清除它们.
前进的更好方法是什么?
我不同意@Gigi.
ViewModel应仅包含与ViewModel/View相关的表示逻辑,例如处理验证或事件(如点击)或格式化视图的输入/输出.但是一个Person无法添加到同一方的Reservation中,可能会在所有地方强制执行,而不仅仅是在你的ViewModel中(即如果你有不同的ViewModel执行类似的操作,你必须重复你的逻辑,这是不好的).
相反,您应该有用于处理预留的服务类,其中包含相关逻辑并将此服务注入ViewModel并从那里调用它的操作.
// Implement interface, if you go for dependency injection or unit tests
public class PartyRegistrationService
{
private RegistrationRepository registrationRepository;
private PartyRepository partyRepository;
private PersonRepository personRepository;
// inject the repositories here, if you use DI
public PartyRegistrationService()
{
this.registrationRepository = new RegistrationRepository();
this.personRepository = new PersonRepository();
this.partyRepository = new PartyRepository();
}
public bool RegisterPersonToParty(int personId, int partyId)
{
Person person = personRepository.GetById(personId);
Party party = partyRepository.GetById(partyId);
// invalid person or party id
if(person==null || party==null)
return false;
if(registrationRepository.GetByPerson(person)!=null)
{
// person has a registration already
return false;
}
// person has no registration yet
var registration = new Registration(person, party);
registrationRepository.Save(registration);
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您的逻辑将耦合到服务类中,并从ViewModel中调用服务RegisterPersonToParty并将ID传递给它.理想情况下,您使用an AsyncRelayCommand来避免在存储库/数据库操作期间的UI锁定.
不要在ViewModels属性中使用这种异步/昂贵/昂贵的操作!
编辑:评论的补充 取决于您是否要使用富域或贫血域(后来被许多现代开发人员劝阻),可以将某些类型的逻辑放入模型中,而将其他逻辑放入模型中则不应该.
遗忘域基本上是模型对象,它根本不包含任何或非常少的(业务)逻辑,所有逻辑都发生在服务类中.
在Rich域中,您基本上将与特定模型相关联的业务逻辑放入模型中,并使服务层保持较薄.
您的需求中的业务逻辑不应该进入某个模型.原因是,您需要的不仅仅是"人"和"派对"数据来应用规则.您还需要Resevation模型,您需要根据一种持久性存储(SQL,本地数据库,Web服务,xml等)进行验证,因此您需要访问存储库来执行此验证.
并且您不应该在模型中访问持久层表单,因为这违反了单一责任原则(一个类应该只负责一件事)并使您的模型依赖于存储库.如果使用依赖注入,那么实例化模型并将存储库注入其中将会有很多麻烦,而不会违反其他模式(即,您的核心不应该依赖于依赖注入框架,因此很难交换您的IoC/DI容器稍后).
@AsyncRelayCommand:即使您希望用户等到操作完成,您也应该使用异步操作.如果您不使用,您的UI将锁定/冻结.这是非常糟糕的用户体验.
有了AsyncRelayCommand你可以做的操作异步和禁用UI容器(变灰所有项目,并防止用户输入),而不是锁定整个应用程序.这也将阻止您的应用程序收到"应用程序未响应"消息.

| 归档时间: |
|
| 查看次数: |
415 次 |
| 最近记录: |