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

4
我正在开发一个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-> DLL)不是最优的。
1. 我如何克服循环依赖?
2. 我构建此Web应用程序的方法是否有效?
3个回答

4
您可以使用洋葱架构,也称为六边形或端口和适配器(同一概念的略微不同变体)。
在此架构中,持久化(数据)层引用您的领域层,因此您的存储库等可以返回领域实体。 为了从领域层使用存储库,您需要将存储库的接口放置在领域层中,并使用IoC容器将其连接到实现(在持久化层中)。
编辑
从您的术语和提供的代码示例来看,似乎您并没有进行DDD,我猜测您包含DDD标签是因为有存储库这个术语,因此我将继续使用非DDD、n层和分层术语。
您将会查看几乎相同的调用堆栈。 它将是Controller→Service→Repository。 理想情况下,您需要在服务中引用“工作单元”,而不是直接引用存储库。
唯一的区别在于项目引用,而不是BLL引用DLL,它将反过来。 您的控制器仍将在BLL中调用服务中的代码。 只是您的BLL服务将不会引用DLL。 因此,为了解决这个问题,您将在BLL中放置DLL存储库的接口,并使用像Ninject或Castle Windsor这样的IoC容器将它们连接起来。
您可能需要查看其他一些主题,例如依赖注入(通过构造函数传递依赖项)、控制反转(IoC)(用于自动实例化配置的接口具体类型的大型全局映射)以及长期目标可能是领域驱动设计(DDD),以了解使用洋葱架构带来的一些优势。

意思是:控制器调用持久层(DLL) -> 调用业务层(具有业务逻辑、领域模型类)。如果是这样,那么遵循这种方法可靠吗?如果我的解释有误,请纠正我。 - Rishu
我已经扩展了我的回答。希望这会有所帮助。我刚意识到,在理解洋葱架构之前,您可能还需要熟悉许多其他术语。 - Adrian Thompson Phillips

2

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

总体问题在于您持久化了视图模型,使业务逻辑层变得多余。如果您选择这条路,可以在DAL中定义实体并在BLL中使用它们,因为它们只有数据。

当您开始关注将域模型与持久性模型分开时,这将是另一个故事,那里您可能会接触到DDD,但您计划的不是DDD。如果您想要一些基本的MVC示例,带有某种DDD,请参考这是我能够快速找到的内容,我相信还有更多可用的示例。该文章提供了MVC和EF的示例,并以合理的术语解释了DDD背后的一些基础知识。我希望它可以成为您的良好起点。Pluralsight还有几门课程可能会对您感兴趣。


这个链接非常有帮助。我应该为DLL创建单独的数据实体,避免使用真实的领域模型,这样做可以帮助我解决循环依赖问题吗?在链接中,BLL调用IRepository并将领域对象发送到DLL。在我的代码中,这导致了循环依赖。你能给一些见解吗? - Rishu

0
循环依赖可能表示设计不良,特别是耦合。如果A依赖于B,而B又依赖于A,则可能缺少第三个实体C。因此,A依赖于B,而两者都依赖于C。多层架构并不一定意味着三层解决方案。在需要时,也可以自由地将业务层拆分为两个程序集。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接