Usm*_*lid 4 asp.net-mvc design-patterns repository-pattern onion-architecture
我正在学习Jeffrey Palermo的Onion Architecture两周多了.我按照本教程创建了一个测试项目.在学习期间,我在SO上遇到了这个问题.根据公认的答案,有人nwang
建议像GetProductsByCategoryId这样的方法不应该在Repository中,而另一方面则Dennis Traub
建议它是Repository的责任.我在做的是:
我有一个通用存储库Domain.Interface
,我有一个方法Find
:
public interface IRepository<TEntity> where TEntity : class
{
IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> filter = null);
.......
.......
.......
}
Run Code Online (Sandbox Code Playgroud)
然后,我创建了一个BaseRepository
在Infrastucture.Data
:
public class RepositoryBase<TEntity> : IRepository<TEntity> where TEntity : class
{
internal readonly DbSet<TEntity> dbSet;
public virtual IEnumerable<TEntity> Find(
Expression<Func<TEntity, bool>> filter = null)
{
IQueryable<TEntity> query = dbSet;
if (filter != null)
{
query = query.Where(filter);
}
return query.ToList();
}
}
Run Code Online (Sandbox Code Playgroud)
我有一个具体的存储库中Infrastructure.Data
public class ProductRepository : RepositoryBase<Product>, IProductRepository
{
public ProductRepository(MyDBContext context)
: base(context)
{
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我在服务层中所做的是将存储库注入服务并调用Repository.Find
类似的方法GetProductsByCategoryId
.喜欢 :
public class ProductService : IProductService
{
private readonly IUnitOfWork _unitOfWork;
private readonly IProductRepository _productRepository;
public ProductService(IUnitOfWork unitOfWork, IProductRepository productRepository)
{
_unitOfWork = unitOfWork;
_productRepository = productRepository;
}
public IList<Product> GetProductsByCategoryId(int CategoryId)
{
// At the moment, My code is like this:
return _productRepository.Find(e => e.CategoryId == CategoryId).ToList();
// My confusion is here. Am I doing it right or I need to take this code to
// ProductRepository and call _productRepositoy.GetProductsByCategoryId(CategoryId) here instead.
// If I do this, then Service Layer will become more of a wrapper around repository. Isn't it?
// My question is : What exactly will be the responsibility of the Service Layer in Onion Architecture?
}
}
Run Code Online (Sandbox Code Playgroud)
您设计应用程序的方式是可以的......但前提是您的服务将处理其他事情,而不仅仅是整理存储库方法!
始终牢记YAGNI原则:
当你真正需要它们时,总是要实现它们,永远不要只是预见到你需要它们
假设您有一个用户故事,说无论何时在您的数据库中找不到产品描述,您都应该从其他地方(调用外部服务或其他东西)进行检索.然后很明显你的ProductService必须有一个
private readonly IProductRepository _productRepository;
Run Code Online (Sandbox Code Playgroud)
还有一个
private readonly IProductDescriptionService _productDescriptionService;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,在存储库之上添加服务层确实很有意义.
我发现,有时为了它而事物可能会被抽象,并且没有任何实际价值.我会说你的例子中的结构很好,并且正确地遵循了模式.正确地说,您的服务层用于满足客户端UI的需求,它与数据层松散耦合,并包含操作数据所需的任何业务逻辑.
我总是认为开始简单并以你的结构为基础比过度抽象,过于复杂和过度膨胀项目更有成效.业务或技术案例通常会推动项目,并决定是否需要.
归档时间: |
|
查看次数: |
4128 次 |
最近记录: |