我对NHibernate相当新,并且在我的存储库类中遇到了一个奇怪的继承链问题。我一直在使用Gabriel Schenker's FAQ作为参考,并且按照他的示例,我一直在创建接口来定义“存储库”类中DAO操作的合同。我正在使用的数据模式相当广泛,过了一会儿我发现自己复制了很多代码。具体来说,在向基本接口添加通用“EntityType”参数后,Add,Update,Delete和“GetByID”方法完全相同。因此,例如,这将是存储库操作的最基本接口:
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);
}
这只是困扰我。它工作正常,但它以错误的方式让我感到困惑,特别是因为使用这个特定模式的继承/实现链可能会非常深入。所以我想我的问题是:
提前致谢。
答案 0 :(得分:7)
一个选项可能是:
public interface IRepository<T> where T: class
{
void Add(T entity);
void Remove(T entity);
void Update(T entity);
T GetByID<IDType>(IDType id);
}
使用实现该接口的基类。即:
public abstract class RepositoryBase<T> : IRepository<T> where T: class
{
...
}
如有必要,将为每种类型的实体进行扩展:
public interface IProductRepository : IRepository<Product>
{
// Add extra methods
}
public class ProductRepository : RepositoryBase<Product>, IProductRepository
{
// Implement extra methods
}