我正在研究MVC项目,我正在遵循分层架构。 在网上阅读和研究之后,我发现拥有单独的层是最佳方法。 所以,我的图层是:
现在,出现了问题:
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)不是最佳的。
答案 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.多层体系结构不一定意味着三层解决方案。您也可以在需要时将业务层拆分为两个程序集。