У меня есть набор репозиториев на основе Entity Framework (EF), некоторые из которых связаны с объектами, которые могут быть мягкими (не все из них могут). Объекты автоматически генерируются EF. До сих пор у меня есть:Мягкий репозиторий при сохранении свойства private
объекты, которые могут быть мягкими удалены реализовать интерфейс 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); }
У меня также есть базовый класс для этих, SoftDeleteRepositoryBase, который расширяет базу RepositoryBase и добавляет методы мягкого удаления:
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 и удалить setter, потому что тогда я не смог бы его модифицировать из SoftDeleteRepositories.
Благодаря
Update: на данный момент я решил проблему путем удаления «набор» из интерфейса и установки значения в хранилище с отражением:
public virtual void Delete(T entity)
{
PropertyInfo propertyInfo = entity.GetType().GetProperty("IsDeleted");
propertyInfo.SetValue(entity, true);
Update(entity);
}
Однако это чувствует себя как патч для меня, я не думаю, что он решает проблему большего дизайна ...
Идея заключается в том, чтобы только разоблачить не -генерированные репозитории. Проблема в том, что если ICustomerRepository является общедоступным, то абстрактный класс RepositoryBase, который он расширяет, также должен быть общедоступным. Это позволило бы людям создавать свои собственные репозитории, расширяя сам репозиторий, и я не хочу ... каких-либо идей вокруг этого? – chuwik
Я хочу использовать генерируемые EF POCOs как DTO, поэтому я бы не пошел на первый вариант. Я подумал о втором, удалив «набор» из интерфейса ICanBeSoftDeleted и установив его с отражением в репозитории. Однако это показалось мне немного «взломанным» ... Были ли проблемы с производительностью? – chuwik
Это не мешает потребителю возиться с удаленным флагом, используя ту же технику, что и вы. –