gpt4 book ai didi

c# - DDD 中的创建日期和创建者放在哪里?

转载 作者:太空狗 更新时间:2023-10-29 20:28:10 26 4
gpt4 key购买 nike

我使用 Entity Framework 并希望使用 DDD 原则。但是,有一些关于实体的信息位于什么是日志记录/持久性信息和什么是关于域对象的信息之间。

在我的情况下,这些都放在一个所有实体都继承自的抽象基类中:

 public abstract class BaseEntity: IBaseEntity
{

/// <summary>
/// The unique identifier
/// </summary>
public int Id { get; set; }

/// <summary>
/// The user that created this instance
/// </summary>
public User CreatedBy { get; set; }

/// <summary>
/// The date and time the object was created
/// </summary>
public DateTime CreatedDate { get; set; }

/// <summary>
/// Which user was the last one to change this object
/// </summary>
public User LastChangedBy { get; set; }

/// <summary>
/// When was the object last changed
/// </summary>
public DateTime LastChangedDate { get; set; }

/// <summary>
/// This is the status of the entity. See EntityStatus documentation for more information.
/// </summary>
public EntityStatus EntityStatus { get; set; }

/// <summary>
/// Sets the default value for a new object
/// </summary>
protected BaseEntity()
{
CreatedDate = DateTime.Now;
EntityStatus = EntityStatus.Active;
LastChangedDate = DateTime.Now;
}

}

现在,如果不提供日期和时间,就无法实例化域对象。但是,我觉得放错地方了。我真的可以为两者争论。也许它根本不应该与域混合?

因为我使用的是 EF Code First,所以把它放在那里是有意义的,否则我还需要创建从 DAL 中的基类继承的新类,复制代码并需要映射到域对象和MVC 模型确实比上面的方法看起来更困惑。

问题:

是否可以在域模型中使用 DateTime.Now?使用 DDD 和 EF Code First,您将此类信息放在哪里? User 应该在域对象中设置还是在业务层中要求它?

更新

我认为 jgauffin 在这里是正确的答案 - 但它确实是一个根本性的变化。但是,在我寻找替代解决方案时,我几乎已经解决了这个问题。如果添加或修改了实体并相应地设置字段,我使用 ChangeTracker.Entries 来查找 ut。这是在我的 UnitOfWork Save() 方法中完成的。

问题是加载导航属性,例如用户(日期时间设置正确)。可能是因为用户是实体继承自的抽象基类的属性。我也不喜欢把字符串放在那里,但是它可能会为某些人解决一些简单的场景,所以我在这里发布解决方案:

        public void SaveChanges(User changedBy)
{
foreach (var entry in _context.ChangeTracker.Entries<BaseEntity>())
{
if (entry.State == EntityState.Added)
{
entry.Entity.CreatedDate = DateTime.Now;
entry.Entity.LastChangedDate = DateTime.Now;
entry.Entity.CreatedBy = changedBy;
entry.Entity.LastChangedBy = changedBy;
}
if (entry.State == EntityState.Modified)
{
entry.Entity.CreatedDate = entry.OriginalValues.GetValue<DateTime("CreatedDate");
entry.Entity.CreatedBy = entry.OriginalValues.GetValue<User>("CreatedBy");
entry.Entity.LastChangedDate = DateTime.Now;
entry.Entity.LastChangedBy = changedBy;
}
}


_context.SaveChanges();
}

最佳答案

Is it Ok to use DateTime.Now in the Domain model at all?

是的。

Where do you put this kind of information using DDD and EF Code First? Should User to be set in the domain object or require it in the Business Layer?

嗯。首先:DDD 模型始终处于有效状态。这对于公共(public)二传手来说是不可能的。在 DDD 中,您使用方法来处理模型,因为这些方法可以确保所有必需的信息都已指定且有效。

例如,如果您可以将某个项目标记为已完成,则 UpdatedAt 日期也可能应该更改。如果您让调用代码确保它很可能会被遗忘在某个地方。相反,你应该有这样的东西:

public class MyDomainModel
{
public void MarkAsCompleted(User completedBy)
{
if (completedBy == null) throw new ArgumentNullException("completedBy");
State = MyState.Completed;
UpdatedAt = DateTime.Now;
CompletedAt = DateTime.Now;
CompletedBy = completedBy;
}
}

阅读我关于该方法的博文:http://blog.gauffin.org/2012/06/protect-your-data/

更新

How to make shure that noone changes the "CreatedBy" and "CreatedDate" later on

我通常有两个适用于数据库的模型构造函数。一种是 protected ,一种可以供我的持久层使用,另一种需要必填字段。将 createdby 放入该构造函数中并在其中设置 createdate:

public class YourModel
{
public YourModel(User createdBy)
{
CreatedDate = DateTime.Now;
CreatedBy = createdby;
}

// for persistance
protected YourModel()
{}
}

然后为这些字段设置私有(private) setter 。

I get a lot of R# warning "Virtual member call in constructor", I've read about it before and it is not supposed to be a good practice.

这通常不是问题。在这里阅读:Virtual member call in a constructor

关于c# - DDD 中的创建日期和创建者放在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12940954/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com