我想扩展这个问题When to update audit fields? DDD。
在我的域模型中,这可能不适合它,但我们有CreatedBy和ModifiedBy的属性,两者都是User,两个值对象。
我是DDD的新手并且对哪个层负责更新这些属性感到困惑......数据?域?或申请?
在上面链接的问题中,他们提到使用事件来更新这些属性......那么假设这些字段在域上是可更新的吗?
以下是我班级的一个例子......
public class SpritePalette
{
private readonly SpritePaletteColors _colors;
public string Id { get; private set; }
public string Name { get; private set; }
public SpritePaletteColors Colors { get { return _colors; } }
public bool IsPublic { get; private set; }
public User CreatedBy { get; private set; }
public DateTime CreatedDate { get; private set; }
public User ModifiedBy { get; private set; }
public DateTime ModifiedDate { get; private set; }
public SpritePalette(
string name)
{
this.Name = name;
this.IsPublic = false;
_colors = new SpritePaletteColors();
}
internal void UpdateId(string value)
{
Validate.IsNotEmpty(value, "Id is required.");
this.Id = value;
}
public void UpdateName(string value)
{
this.Name = value;
}
public void MarkAsCreated(User value)
{
this.CreatedBy = value;
this.CreatedDate = DateTime.UtcNow;
}
public void MarkAsModified(User value)
{
this.ModifiedBy = value;
this.ModifiedDate = DateTime.UtcNow;
}
public bool HasColor(string color)
{
return _colors.HasColor(color);
}
public void AddColor(string color)
{
_colors.AddColor(color);
}
public void RemoveColor(string color)
{
_colors.RemoveColor(color);
}
public void UpdateIsPublic(bool value)
{
this.IsPublic = value;
}
}
我雇佣了两个方法,一个用于将模型标记为已创建,一个用于更新CreatedBy和CreatedDate,另一个用于将模型标记为已修改。
对于DDD,这是否可以接受?处理这些更新审计属性的更好方法是什么?有更好的方法,即使用事件吗?
我承认这有点主观,但感谢任何人都可以提供的任何帮助!
答案 0 :(得分:1)
使用"框架"
的解决方案一个。使用额外参数公开每个构造函数和命令方法。 像:
public SpritePalette(
string name, User user)
{
this.Name = name;
this.IsPublic = false;
_colors = new SpritePaletteColors();
createdBy(user)
}
public void UpdateName(string value, User user)
{
this.Name = value;
modifiedBy(user);
}
internal void modifiedBy(User value)
{
this.CreatedBy = value;
this.CreatedDate = DateTime.UtcNow;
}
在这种情况下,每次应用程序层操作域模型时,都会更新审计字段。但是当应用程序层调用以下几个命令方法时,这可能看起来很简单:
//application layer
public void update(String name, String description, ....other attributes,User user) [
//retrieve SpritePalette
SpritePalette.updateName(name, user);
SpritePalette.updateDescription(description, user);//passes user again
//other command methods invocation //passes user again & again
}
B中。公开额外的审计字段更新方法。
像:
//application layer
public void update(String name, String description, ....other attributes,User user) [
//retrieve SpritePalette
SpritePalette.updateName(name);
SpritePalette.updateDescription(description);
//other command methods invocation
SpritePalette.modifiedBy(user);
}
但我有时害怕忘记调用这个modifiedBy()方法。
没有"框架"
的解决方案也许我们应该使用另一组模型。如果我们将更新行为建模为事件怎么办?核心域不需要审计字段。查询要求通常需要审核字段,例如"我想看看谁修改了这个东西"。
让我们分开:
class UpdateNameEvent {
string SpritePaletteId;
string name;
User user;
Date when;
}
class SpritePalette{
on(UpdateNameEvent event) {
this.Name = event.name();//no user involved
}
}
//application layer
public void update(String name, User user) [
//retrieve SpritePalette
var event = new UpdateNameEvent(name, user);
SpritePalette.on();
//other command methods invocation
events.save(event); //save the events
repository.update(SpritePalette);
}
public List<SpritePaletteEvent> list(string id) {
return events.list(id);
}
答案 1 :(得分:1)
在您上面链接的问题中,CreatedBy
和UpdatedBy
是域层的一部分,因为实际的域会议实际上是由某人安排的。
在您的设置(精灵)中,CreatedBy
和UpdatedBy
似乎不太可能是底层图形域的一部分。因此,CreatedBy
/ UpdatedBy
属性仅用于簿记/审核,因此是纯粹的应用程序级别问题,应仅在应用程序级别处理。在Java中,您通常会通过某些Interceptor更新这些标志,但我不确定如何在C#中执行此操作。也许可以更新存储库中的这些字段(通过让应用程序在工作单元或类似工具中注册当前用户)。