我正在尝试使用域驱动开发(DDD)来实现我的新ASP.NET MVC2项目和实体框架4.在做了一些研究后,我想出了以下层约定,每个层都在自己的类项目中:
MyCompany.Domain
public class User
{
//Contains all the properties for the user entity
}
public interface IRepository<T> where T : class
{
IQueryable<T> GetQuery();
IQueryable<T> GetAll();
IQueryable<T> Find(Func<T, bool> condition);
T Single(Func<T, bool> condition);
T First(Func<T, bool> condition);
T GetByID(int id);
void Delete(T entity);
void Add(T entity);
void Attach(T entity);
void SaveChanges();
}
public interface IUserRepository: IRepository<User> {}
public class UserService
{
private IUserRepository _userRepository;
public UserService(IUserRepository userRepository)
{
_userRepository = userRepository;
}
// This class will hold all the methods related to the User entity
}
MyCompany.Repositories
public class UserRepository : IRepository<User>
{
// Repository interface implementations
}
MyCompany.Web - &gt;这是MVC2项目
目前,我的Repositories图层包含对Domain图层的引用。根据我的理解,将UserRepository注入UserService类可以很好地进行单元测试,因为我们可以传入虚假的用户存储库。因此,使用此体系结构,我的Web项目看起来需要引用我的域和存储库层。但这是有效的吗?因为历史上表示层只有对业务逻辑层的引用。
答案 0 :(得分:10)
答案 1 :(得分:8)
这非常有效,实际上与我们的设置非常相似。
但是在您的问题中,您在域项目中有IRepository
,我会将其放入您的存储库程序集中。
您的域图层应该包含您的域实体和业务逻辑。 您的存储库层应该具有通用存储库接口,以及针对每个聚合根的一个具体实现。
我们还有一个服务层,用于在UI(控制器)和存储库之间进行调解。这允许中心位置放置不属于存储库的逻辑 - 诸如分页和验证之类的东西。
这样,UI不会引用存储库,只引用服务层。
我们还使用DI将EntityFrameworkRepository注入我们的服务层,并将MockRepository注入我们的测试项目。
您似乎走在正确的轨道上,但由于它似乎想要“DDD-All-The-Way”,您是否考虑过实施工作单元模式来管理多个存储库分享相同的背景?
答案 2 :(得分:0)
您可能想要探索Sharp Architecture框架解决此问题的方式,因为看起来您基本上是在重新实现相同的想法。 Northwind application tutorial对这些概念进行了很好的讨论。