私はEntityFrameworkを使用しており、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;
}
}
現在、ドメインオブジェクトは、日付と時刻を指定せずにインスタンス化することはできません。しかし、それを置くのは間違った場所だと思います。私は本当に両方について議論することができます。多分それはドメインと全く混合されるべきではありませんか?
私はEFCodeFirstを使用しているので、そこに配置するのが理にかなっています。そうしないと、DALの基本クラスから継承する新しいクラスを作成し、コードを複製して、ドメインオブジェクトとMVCモデルの両方にマップする必要があります。上記のアプローチよりも厄介に見えます。
質問):
ドメインモデルでDateTime.Nowを使用しても大丈夫ですか?DDDとEFコードファーストを使用して、この種の情報をどこに配置しますか?ユーザーをドメインオブジェクトに設定する必要がありますか、それともビジネスレイヤーで要求する必要がありますか?
アップデート
jgauffinはここで正しい答えだと思いますが、それは本当に根本的な変化です。しかし、別の解決策を探していたところ、ほとんどこれで解決できました。ChangeTracker.Entriesを使用して、エンティティが追加または変更されているかどうかを確認し、それに応じてフィールドを設定しました。これは私のUnitOfWorkSave()メソッドで行われます。
問題は、Userなどのナビゲーションプロパティの読み込みです(DateTimeが正しく設定されています)。これは、ユーザーがエンティティの継承元の抽象基本クラスのプロパティであるためである可能性があります。私もそこに文字列を入れるのは好きではありませんが、誰かのためにいくつかの簡単なシナリオを解決するかもしれないので、ここに解決策を投稿します:
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();
}