这是一个简化的ViewModel:
public class EditViewModel : BaseViewModel
{
private Item _currentItem;
public Item CurrentItem
{
get
{ return _currentItem; }
set
{
if (_currentItem != value)
{
_currentItem = value;
OnPropertyChanged("CurrentItem");
}
}
}
private ObservableCollection<Property> _itemProperties;
public ObservableCollection<Property> ItemProperties
{
get { return _itemProperties; }
set
{
_itemProperties = value;
OnPropertyChanged("ItemProperties");
}
}
public void AddProperty() //this is called from an ICommand
{
Property p = new Property{ ItemId = CurrentItem.ItemId };;
CurrentItem.Properties.Add(p);
ItemProperties.Add(p);
}
}
我想做的是将这里的业务逻辑分离到一个单独的类中。它使所有烦人的MVVM样板都脱离了有用的内容,并且从理论上讲应导致将代码组织为更具可测试性的状态。
我们通过创建从BaseViewModel继承的单独的“Logic”类开始,然后从其逻辑类继承实际的ViewModel来开始这样做。所以:
public class EditLogic : BaseViewModel
{ }
public class EditViewModel : EditLogic
{ }
然后,逻辑进入逻辑类。
对于某些业务逻辑而言,这种分离很简单-干净利落。但是,在上面给出的示例中,我看不到没有很多不必要的麻烦的简单方法即可退出该方法。像这样(未经测试):
public class EditLogic : BaseViewModel
{
public Property GetNewProperty(Item currentItem)
{
Property p = new Property{ ItemId = currentItem.ItemId };
currentItem.Properties.Add(p);
return p;
}
}
public class EditViewModel : BaseViewModel
{
public void AddProperty() //this is called from an ICommand
{
ItemProperties(GetNewProperty(CurrentItem))
}
}
这似乎令人困惑-因为它依赖于CurrentItem隐式地通过引用传递-并且不必要地卷积而没有太大的收获。
当然,这是一个非常简单的示例,不值得大惊小怪。但是它说明了一点,在MVVM中,为方便起见,最终很容易将演示文稿/绑定(bind)代码与业务逻辑混合在一起。
我可以将某些属性从EditViewModel移到EditLogic,但是首先我们失去了将这两个属性分开的优势。
所以:值得为此烦恼吗?如果是这样,我们应该走多远?还有保持隔离的更好方法吗?
最佳答案
您正在寻找的是服务。
public interface IPropertyService
{
Property GetNewProperty(Item currentItem);
}
您当然需要一个实现:
public class MyPropertyService : IPropertyService
{
public Property GetNewProperty(Item currentItem)
{
//TODO
}
}
然后,您可以将此服务作为依赖项注入(inject)到 View 模型的构造函数中。
public class MyViewModel
{
private IPropertyService _PropertyService;
public MyViewModel(IPropertyService propertyService)
{
_PropertyService = propertyService;
}
public void AddProperty() //this is called from an ICommand
{
Property p = _PropertyService.GetProperty(CurrentItem);
CurrentItem.Properties.Add(p);
ItemProperties.Add(p);
}
}
这将确保您不需要为业务逻辑创建大量的 View 模型基类。取而代之的是,将业务逻辑封装在服务中,然后将它们传递到依赖于它们的 View 模型中。
关于c# - MVVM中分离业务逻辑的距离,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33564054/