业务逻辑和数据访问层的循环依赖关系

时间:2016-03-13 18:08:53

标签: model-view-controller architecture domain-driven-design repository-pattern business-logic-layer

我正在研究MVC项目,我正在遵循分层架构。 在网上阅读和研究之后,我发现拥有单独的层是最佳方法。 所以,我的图层是:

  • 表示层具有:控制器,视图
  • 业务层:单独的类库项目(包括域模型(表示表实体),业务逻辑服务,ViewModel的单独文件夹)
  • 数据访问层:调用数据库(SQL语句,连接)

现在,出现了问题:

BLL调用数据访问层:

    public PartnerOperation(IDataAccess dataRepository)
    {
        _dataAccess = dataRepository;
    }

    public void InsertRequest(PartnerRequestModel partnerRequestModel)
    {
      _dataAccess.InsertIntoDB(partnerRequestModel); //Domain object passed to DLL method
    }

现在,我的BLL依赖于依赖于BLL的数据访问层,因为域对象在BLL内部。所以,两者都互相参考。

我正在严格地搜索它几个星期,但无法找到出路。

我已经经历过了 Business Logic Layer and Data Access layer: circular dependency但它并没有完全解决我的问题。

有些网站支持图层架构,有些人认为洋葱方法更好。 例如:this article声称这整个方法(Controller - > BLL - > DLL)不是最佳的。

  1. 我如何克服循环依赖?
  2. 我构建此Web应用程序的方法是否有效?

3 个答案:

答案 0 :(得分:2)

业务对象与数据对象不同。您的业​​务对象应包含业务登录,而数据对象则用于持久性。如果使用简单的分层体系结构,则可以在需要在层之间发送数据时将业务对象映射到数据对象。您可以通过编写映射代码或使用Automapper等工具进行映射。

这里的总体问题是你坚持你的视图模型,使业务逻辑层变得多余。如果选择此路径,则可以在DAL中定义实体并在BLL中使用它们,因为它们只有数据。

当您开始关注将您的域模型与持久性模型分开时,这将是另一个故事,您可能会来DDD,但您计划的不是DDD。如果你想在MVC上使用某种DDD this is what I was able to find quickly获得一些基本样本,我相信还有更多的样本可用。本文给出了MVC和EF的例子,并以合理的方式解释了DDD背后的一些基础知识。我希望它对你来说是一个很好的起点。您可能还会对Pluralsight上的一些课程感兴趣。

答案 1 :(得分:2)

您可以使用洋葱架构,也称为六边形或端口和端口。适配器(同一事物的变化略有不同)。

使用此体系结构,您的持久性(数据)层引用您的域层,因此您的存储库等可以返回域实体。为了使用域层中的存储库,您需要将存储库的接口放在域层中,并使用IoC容器将它们连接到实现(在持久层中)。

修改

听起来好像你从你的术语和你提供的代码样本中做DDD,我猜你已经包含了DDD标签因为术语库,所以我将继续使用非DDD,n层和分层术语。

你会看到一个几乎相同的调用堆栈。这将是控制器 - >服务 - >库。理想情况下,您需要在服务中引用“工作单元”,而不是直接引用存储库。

唯一的区别是项目引用,而不是引用DLL的BLL,它将是另一种方式。您的控制器仍将在BLL中的服务中调用代码。只是你的BLL服务没有对​​DLL的引用。因此,为了解决这个问题,您可以将DLL存储库中的接口放入BLL中,并使用像Ninject或Castle Windsor这样的IoC容器进行连接。

您可能需要查看一些其他主题,例如依赖注入(DI)(通过构造函数传递依赖关系),控制反转(IoC)(自动实例化已配置的具体接口类型的大型全局映射)和对于长期目标,可能采用域驱动设计(DDD)来理解使用洋葱架构所带来的一些优势。

答案 2 :(得分:0)

循环依赖可能表示不良设计,尤其是耦合。如果A依赖于B而B依赖于A,那么您可能缺少第三个实体C.因此A依赖于B并且两者都依赖于C.多层体系结构不一定意味着三层解决方案。您也可以在需要时将业务层拆分为两个程序集。