我完全同意耿祖的观点。
我已经在多个项目中使用了这种方法,在我作为解决方案架构师的角色中,我希望团队中的所有开发人员只编写必要和特定的代码。
我的经验是,您大多数时候都需要删除和查找方法等。您不希望这样做的情况不应该规定。结果将是需要删除的存储库都必须实现这一点,这将是冗余代码。所有这些 Delete 方法都可以由 GenericRepository 抽象类实现。该类可以针对 NHibernate 工作并将通用实体作为 T。然后,当您想要创建例如 UserRepository 时,它将从 GenericRepository 和 IUserRepository 继承。
其中 IUserRepository 从 IRepository 继承。我将添加一些代码:
public class UserRepository : GenericNHibernateRepository<User, int>, IUserRepository
{
#region IUserRepository Members
public User GetUserByEmail(string email)
{
ICriterion[] query = {Restrictions.Eq("Email", email)};
var list = GetByCriteria(query);
if (list.Count == 0)
return null;
else
return list[0];
}
#endregion
}
public interface IUserRepository : IRepository<User, int>
{
User GetUserByEmail(string email);
}
public interface IRepository<T, ID> where T : IAggregateRoot
{
T GetById(ID id);
List<T> GetAll();
T Save(T entity);
T SaveOrUpdate(T entity);
void Delete(T entity);
void Flush();
}
那么有什么好处。有巨大的!
正如您在 IRepository 接口中看到的那样,我们只允许 IAggregateRoot 拥有一个存储库(DDD 指南)。
所有存储库删除都将命名为 Delete(没有开发人员将其命名为 Remove 等,并且它仅在一个地方实现,即 GenericNHibernate 类)。
如果我团队中的开发人员想要为实体创建新存储库,唯一的代码是
公共类 CustomerRepositoryNHibernate : GenericNHibernateRepository, ICustomerRepository {}
然后您就可以读取、删除、查找功能...您的名字。不错。
但是,如果您使用依赖注入和 IoC 框架,我可以说,例如 Windsor Castle,您可以创建一个工具来加载所有实现 IRepository 接口并位于组件中的存储库(例如 MyProject.Infrastructure 。数据)。这为您的团队提供了极大的推动力。
首先,您的开发人员在 MyProject.Infrastructure.Data 中创建一个新的存储库,并使用上面示例中的代码行。
第二次在应用程序启动时,Windsor Castle 设施将使其可用于注入。
所以你的开发人员可以继续编写一个控制器或服务类
IComnpanyRepository 作为构造函数参数及其全部。