Я довольно новичок в NHibernate и столкнулся со странной проблемой цепочки наследования в моих классах репозитория. Я использовал FAQ Габриэля Шенкера в качестве справочного материала и, следуя его примерам, я создавал интерфейсы для определения контрактов для операций DAO в классах "репозитория". Схема данных, с которой я работаю, довольно обширна, и через некоторое время я обнаружил, что дублирую много кода. В частности, методы Add, Update, Delete и «GetByID» были точно такими же после того, как я добавил универсальный параметр «EntityType» в базовый интерфейс. Так, например, это будет самый простой интерфейс для операций с репозиторием:
public interface IBasicRepository<EntityType> where EntityType : class
{
void Add(EntityType entity);
void Remove(EntityType entity);
void Update(EntityType entity);
EntityType GetByID<IDType>(IDType id);
}
Теперь я буду просто говорить о методе Add для краткости. С универсальным EntityType реализации были одинаковыми:
public void Add(EntityType entity)
{
using (ISession session = NHUtility.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
session.Save(entity);
transaction.Commit();
}
}
}
Очевидно, что многократный ввод текста одного и того же метода (с небольшим изменением типа) не только раздражает, это плохой дизайн в моей книге. Поэтому я создал абстрактный базовый класс, который я назову RepositoryBase, который обеспечивает реализацию для Add (). Поскольку вместо интерфейса я использую реферат, я «разрываю цепочку интерфейсов» для классов, унаследованных от RepositoryBase, и вынужден также делать любые деривации абстрактными, даже если использование интерфейса кажется более «правильным». Используя этот дерьмовый пример маленькой сущности ....
public class Entity1
{
public Guid ID { get; set; }
public String Name { get; set; }
}
... никто не может этого сделать ...
public interface IEntity1Repository : RepositoryBase<Entity1>
{
//Illegal!!!! Bad, naughty programmer!
}
... но это нормально ....
public abstract class Entity1RepositoryBase : RepositoryBase<Entity1>
{
public abstract ICollection<Entity1> GetByName(string name);
}
Это меня просто беспокоит. Это работает, но это меня теряет, особенно потому, что цепочка наследования / реализации с этой конкретной схемой может идти довольно глубоко. Итак, я думаю, мои вопросы:
- Разве я просто глуп и сдерживаюсь по этому поводу?
- Есть ли другой / лучший дизайн, на который я должен смотреть здесь? Я рассмотрел некоторые другие примеры (в частности, Билли МакКафферти ), и подход Шенкера кажется самым простым для новичка в NHibernating.
Заранее спасибо.