Model view controller 业务逻辑和数据访问层的循环依赖

Model view controller 业务逻辑和数据访问层的循环依赖,model-view-controller,architecture,domain-driven-design,repository-pattern,business-logic-layer,Model View Controller,Architecture,Domain Driven Design,Repository Pattern,Business Logic Layer,我正在从事MVC项目,我遵循分层体系结构。 在网上阅读和研究之后,我发现分层是最好的方法。 因此,我的图层是: 表示层有:控制器、视图 业务层:单独的类库项目(包括域模型(表示表实体)、业务逻辑服务、ViewModels的单独文件夹) 数据访问层:具有对数据库的调用(SQL语句、连接) 现在,问题出现了: 对数据访问层的BLL调用: public PartnerOperation(IDataAccess dataRepository) { _dataAcces

我正在从事MVC项目,我遵循分层体系结构。 在网上阅读和研究之后,我发现分层是最好的方法。 因此,我的图层是:

  • 表示层有:控制器、视图
  • 业务层:单独的类库项目(包括域模型(表示表实体)、业务逻辑服务、ViewModels的单独文件夹)
  • 数据访问层:具有对数据库的调用(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中。因此,两者都相互参照

我花了几周的时间在上面苦苦搜寻,但找不到出路

我已经经历过了 但这并不能完全解决我的问题

有些网站支持层次结构,有些网站声称洋葱式的方法更好。 例如:声称整个方法(Controller->BLL->DLL)不是最优的

  • 如何克服循环依赖性
  • 我构建这个Web应用程序的方法有效吗

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

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


    当您开始考虑将域模型与持久性模型分开时,这将是另一个故事,您可能会想到DDD,但您计划的不是DDD。如果您想在MVC上使用某种DDD的基本示例,我相信还有更多示例可用。本文给出了MVC和EF的示例,并合理地解释了DDD背后的一些基础知识。我希望这能成为你的一个好的起点。您可能还对Pluralsight上的几门课程感兴趣。

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

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


    当您开始考虑将域模型与持久性模型分开时,这将是另一个故事,您可能会想到DDD,但您计划的不是DDD。如果您想在MVC上使用某种DDD的基本示例,我相信还有更多示例可用。本文给出了MVC和EF的示例,并合理地解释了DDD背后的一些基础知识。我希望这能成为你的一个好的起点。您可能还对Pluralsight上的几门课程感兴趣。

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

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

    您可以使用洋葱式体系结构,也称为六角形或端口和适配器(在同一事物上略有不同)

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

    编辑

    这听起来不像是根据您提供的术语和代码示例进行DDD,我猜您之所以包含DDD标记是因为术语库,所以我将继续使用非DDD、n层和分层术语

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

    唯一的区别是项目引用,而不是BLL引用DLL,相反。控制器仍将调用BLL中服务中的代码。只是你的BLL服务没有对DLL的引用。为了解决这个问题,您将DLL存储库中的接口放在BLL中,并使用IoC容器(如Ninject或Castle Windsor)将它们连接起来

    您可能需要研究其他一些主题,如依赖项注入(DI)(通过构造函数传递依赖项)、控制反转(IoC)(配置的具体接口类型的自动实例化的大型全局映射)以及长期目标可能是域驱动设计(DDD)去理解你想要的一些优势