我不确定,但只要我读过ddd,域模型就永远不会离开应用层。。如果这是真的,那么视图模型如何重用领域模型的行为?
假设ddd透视中的以下发票模型
public class Invoice
{
public int Id { get; set; }
public int CustomerID { get; internal set; }
public void ChangeCustomer(Customer customer)
{
if (customer.IsActive == false)
throw new Exception("Inactive customers cannot be used");
CustomerID = customer.Id;
//other properties change also that need to be reflected to the user interface
}
}
现在让我们进行发票ViewModel尝试#1。按照这个想法,我没有重用域行为的问题,但在这种情况下,域层必须引用到UI项目(WPF(。但我担心的是,我们不应该在应用层之外使用域层
public class InvoiceVMOption1 : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyUI(string PropertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
}
Invoice underlinesource;
public InvoiceVMOption1(Invoice underlinesource)
{
this.underlinesource = underlinesource;
}
public int InvoiceID { get => underlinesource.Id; }
public int CustomerID
{
get => underlinesource.CustomerID;
set
{
try
{
//This is a very simple example. in reality when changing customer other properties of the domain change also.
var customer = new CustomerService().Get(value);
underlinesource.ChangeCustomer(customer);
NotifyUI(nameof(CustomerID));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
throw;
}
}
}
}
现在让我们有发票视图模型选项#2按照这个想法,这意味着应用程序服务负责构建视图模型并将其提供给UI,然后UI返回视图模型>转换到域>通过存储库更新
/// <summary>
/// I like more this idea as it decouple viewmodel from domain layer
/// The problem here is how i can reuse the logic of changing the customer since domain model is not referenced
/// </summary>
public class InvoiceVMOption2 : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyUI(string PropertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
}
private int invoiceid;
public int InvoiceID
{
get => invoiceid;
set
{
invoiceid = value;
NotifyUI(nameof(InvoiceID));
}
}
private int customerid;
public int CustomerID
{
get => customerid;
set
{
//user select a customer from combobox binding with his id
//here we need to let the user whenever any of the validation that exists in domain model invoice will fail when changing customer.
//nothing will save yet
//after user finish this viewmodel will be sent to application layer(service) convert it to domain and update through repository
//Problem is, how i can know if customer will fail to change without writing same code validation from domain?
customerid = value;
NotifyUI(nameof(customerid));
}
}
}
视图模型是一条单行道。它只意味着从域表示构建适合UI的数据结构。
UI中的每个更改都可以更好地建模为单独的命令(如果使用CQRS(或调用特定应用程序服务的不同API(如果使用核心DDD(
通过选择对每个更改进行建模,可以在代码中更准确地表示域。如果要返回对数据结构进行修改的同一视图模型,则隐藏了这些更改的意图。流模式也更接近CRUD,因为您只是将数据传输到后端以进行持久化。