Ste*_*ios 2 c# wpf domain-driven-design behavior viewmodel
我不确定,但只要我读到有关 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
}
}
Run Code Online (Sandbox Code Playgroud)
现在让发票 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;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在让我们拥有 Invoice ViewModel 选项 #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));
}
}
}
Run Code Online (Sandbox Code Playgroud)
视图模型是一条单向街道。它只是为了从域表示构建适合 UI 的数据结构。
UI 上的每个更改最好建模为单独的命令(如果您使用的是 CQRS)或调用特定应用程序服务的不同 API(如果您使用的是核心 DDD)。
通过选择对每个更改进行建模,您可以在代码中更准确地表示域。如果您要返回对数据结构进行修改的相同视图模型,则隐藏了这些更改的意图。流程模式也更接近 CRUD,因为您只需将数据传输到后端进行持久化。
归档时间: |
|
查看次数: |
1029 次 |
最近记录: |