私は一連の Entity Framework (EF) ベースのリポジトリを持っています。そのうちのいくつかは、論理的に削除できるエンティティを処理します (すべてが削除できるわけではありません)。エンティティは EF によって自動生成されます。これまでのところ、私は持っています:
論理的に削除できるエンティティは、ICanBeSoftDeleted インターフェイスを実装します。
public interface ICanBeSoftDeleted { bool IsDeleted { get; set; } }
これらのエンティティには、ISoftDeleteRepository を実装するリポジトリを使用します。
public interface ISoftDeleteRepository<T> : IRepository<T> where T : class, ICanBeSoftDeleted { void SoftDelete(T entity); void SoftDelete(Expression<Func<T, bool>> where); }
また、RepositoryBase を拡張してソフト削除メソッドを追加する SoftDeleteRepositoryBase という基本クラスもあります。
public abstract class SoftDeleteRepositoryBase<T> : RepositoryBase<T> where T : class, ICanBeSoftDeleted { public virtual void SoftDelete(T entity) { entity.IsDeleted = true; Update(entity); } public virtual void SoftDelete(Expression<Func<T, bool>> where) { var entitiesToDelete = GetMany(where).AsEnumerable(); foreach (T entity in entitiesToDelete) { this.Delete(entity); } } }
これはすべてうまくいきます。ただし、このコードは、リポジトリを直接呼び出すユーザーに配布される内部ライブラリの一部であり、「IsDeleted」プロパティを変更したり、メソッドを呼び出すエンティティのみを読み取ったり削除したりしたくありません。セッターが公開されているため、現在、彼らはそれを行うことができます。
これを行うためにコード設計を変更するにはどうすればよいですか? ICanBeSoftDeleted を変更してセッターを削除することはできません。これは、SoftDeleteRepositories から変更することができないためです。
ありがとう
更新:今のところ、インターフェイスから「セット」を削除し、リフレクションを使用してリポジトリに値を設定することで問題を解決しました:
public virtual void Delete(T entity)
{
PropertyInfo propertyInfo = entity.GetType().GetProperty("IsDeleted");
propertyInfo.SetValue(entity, true);
Update(entity);
}
ただし、これはパッチのように感じます。より大きな設計上の問題を解決しているとは思いません...