洋葱架构 - 服务层的责任 [英] Onion Architecture - Service Layer Responsibility

查看:114
本文介绍了洋葱架构 - 服务层的责任的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我学习建筑学洋葱杰弗里巴勒莫超过2个星期了。我创建遵循本教程一个测试项目。在研究我碰到上所以这个问题。根据公认的答案,一个人 nwang 显示,像GetProductsByCategoryId方法不应该是库和一个另一方面丹尼斯·特劳布
顾名思义是库的责任。什么我做的是:

我有一个通用存储库在 Domain.Interface 在我所的方法查找

 公共接口IRepository< TEntity>其中,TEntity:类
{
     IEnumerable的< TEntity>查找(前pression<&Func键LT; TEntity,布尔>>过滤器= NULL);
     .......
     .......
     .......
}

然后,我创建了一个 BaseRepository Infrastucture.Data

 公共类RepositoryBase< TEntity> :IRepository< TEntity>其中,TEntity:类
{
     内部只读DbSet< TEntity> dbSet;
     公共虚拟IEnumerable的< TEntity>找(
            防爆pression<&Func键LT; TEntity,布尔>>过滤器= NULL)
     {
            IQueryable的< TEntity>查询= dbSet;            如果(过滤器!= NULL)
            {
                查询= query.Where(过滤器);
            }
            返回query.ToList();
     }
}

和我在 Infrastructure.Data

具体信息库

 公共类ProductRepository:RepositoryBase<产品>中IProductRepository
{
      公共ProductRepository(MyDBContext上下文)
           :基座(上下文)
       {       }
}

我在我的服务层我做的是注射进库服务,并呼吁

现在 Repository.Find GetProductsByCategoryId 。这样的:

 公共类ProductService:IProductService
{
     私人只读IUnitOfWork _unitOfWork;
     私人只读IProductRepository _productRepository;     公共ProductService(IUnitOfWork的UnitOfWork,IProductRepository productRepository)
     {
          _unitOfWork =的UnitOfWork;
          _productRepository = productRepository;
     }     公众的IList<产品与GT; GetProductsByCategoryId(INT的CategoryId)
     {
          //此刻,我的code是这样的:
          返回_productRepository.Find(E => e.CategoryId ==类别ID).ToList();          //我的困惑就在这里。我是这样做是正确还是我需要借这个code到
          // ProductRepository并调用_productRepositoy.GetProductsByCategoryId(类别ID),而不是在这里。
          //如果我这样做,那么服务层将变得更加库周围的包装的。难道不是吗?
          //我的问题是:究竟会在洋葱架构服务层的责任?
         }
    }


解决方案

您设计您的应用程序是确定......但只有当你的服务会来处理其他事情不只是包库方法的方式!

始终牢记的 YAGNI原则,上面写着:


  

始终贯彻的事情,当你真正需要他们,从来没有当你只是预见到,你需要他们。


假设你有一个用户故事,说,只要在你的数据库中找不到一个产品说明,你应该从别的地方retreive它(调用外部服务或东西)。然后,它似乎是显而易见的,你的ProductService将必须有一个

 私人只读IProductRepository _productRepository;

,而且一

 私人只读IProductDescriptionService _productDescriptionService;

在这种情况下真的很有意义在您的仓库的顶部添加一个服务层。

I am learning Onion Architecture by Jeffrey Palermo for more than 2 weeks now. I have created a test project by following this tutorial. While studying I came across this question on SO. According to accepted answer, one person nwang suggests that Methods like GetProductsByCategoryId should not be in Repository and one the other hand Dennis Traub suggests that it is the responsibility of the Repository. What I am doing is :

I have a General Repository in Domain.Interface in which I have a method Find :

public interface IRepository<TEntity> where TEntity : class
{
     IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> filter = null);
     .......
     .......
     .......
}

Then I created a BaseRepository in 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();
     }
}

And I have a concrete repository in Infrastructure.Data

public class ProductRepository : RepositoryBase<Product>, IProductRepository
{
      public ProductRepository(MyDBContext context)
           : base(context)
       {         

       }
}

Now what I am doing in my Service Layer is Injecting Repository into Service and calling Repository.Find for methods like GetProductsByCategoryId. Like :

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?
         }
    }

解决方案

The way you designed your application is ok... but only if your service will come to handle other things than just wrap up the repository methods!

Always keep in mind the YAGNI principle that says:

Always implement things when you actually need them, never when you just foresee that you need them

Let's say that you have a user story that says that whenever a product description is not found in your DB, you should retreive it from somewhere else (calling an external service or something). Then it seems obvious that your ProductService will have to have a

private readonly IProductRepository _productRepository;

but also a

private readonly IProductDescriptionService _productDescriptionService;

In that situation it really makes sense to add a service layer on top of your repositories.

这篇关于洋葱架构 - 服务层的责任的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆