我对NHibernate相当新,并且在我的存储库类中遇到了一个奇怪的继承链问题.我一直在使用Gabriel Schenker的FAQ作为参考,并且按照他的例子,我一直在创建接口来定义"存储库"类中DAO操作的合同.我正在使用的数据模式相当广泛,过了一会儿我发现自己复制了很多代码.具体来说,在向基本接口添加通用"EntityType"参数后,Add,Update,Delete和"GetByID"方法完全相同.因此,例如,这将是存储库操作的最基本接口:
public interface IBasicRepositorywhere EntityType : class { void Add(EntityType entity); void Remove(EntityType entity); void Update(EntityType entity); EntityType GetByID (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{ //Illegal!!!! Bad, naughty programmer! }
......但这很好......
public abstract class Entity1RepositoryBase : RepositoryBase{ public abstract ICollection GetByName(string name); }
这只是困扰我.它有效,但它以错误的方式让我感到困惑,特别是当这个特定模式的继承/实现链可能会非常深入时.所以我想我的问题是:
我只是愚蠢和肛门保持这个?
我应该在这里看一下不同/更好的设计吗?我看了一些其他的例子(特别是Billy McCafferty的),而Schenker的方法对新手NHibernating来说似乎最简单.
提前致谢.
一种选择可能是:
public interface IRepositorywhere T: class { void Add(T entity); void Remove(T entity); void Update(T entity); T GetByID (IDType id); }
使用实现该接口的基类.即:
public abstract class RepositoryBase: IRepository where T: class { ... }
如有必要,将针对每种类型的实体进行扩展:
public interface IProductRepository : IRepository{ // Add extra methods } public class ProductRepository : RepositoryBase , IProductRepository { // Implement extra methods }