传统的 3 层架构与 IOC 的 3 层
Posted
技术标签:
【中文标题】传统的 3 层架构与 IOC 的 3 层【英文标题】:Traditional 3 tier architecture vs 3 tier with IOC 【发布时间】:2012-07-05 12:02:03 【问题描述】:我正在构建一个包含表示层 (PL)、业务逻辑层 (BLL) 和数据访问层 (DAL) 的 3 层架构。 传统的 3 层架构逻辑规定 BLL 应充当 PL 和 DAL 之间的中介。 PL 甚至不应该知道存在数据库,而 DAL 不应该知道存在 BLL 或 PL。
上述实施将在 3 个不同的物理项目之间创建以下依赖关系,如下所示
PL 项目 -> BLL DLL 参考 BLL 项目 -> DAL DLL 参考 DAL 项目 -> 无参考
然而,通过在 BLL 中定义接口以供 DAL 实现并通过构造函数注入使用 DI 在 BLL 和 DAL 之间应用 IOC 的概念,将改变依赖关系,如下所示
PL 项目 -> BLL DLL 参考,DAL DLL 参考(用于具体类型的 DI 到 BLL 对象的构造函数) BLL 项目 -> 无参考 DAL 项目 -> BLL DLL 参考(用于实现 BLL 接口)
那么,IOC 和传统的 3 层有冲突吗?
理想情况下,我希望实现以下目标,同时通过 DI 维持我的 IOC。
PL 项目 -> BLL DLL 参考 BLL 项目 -> 无参考 DAL 项目 -> BLL DLL 参考
你是怎么做到的?
【问题讨论】:
老问题,但我认为这个其他 SO 答案可以提供帮助:***.com/questions/9501604/…。基本上,您不希望您的 BLL 引用 DAL,而是使用您的 IoC 容器注入它。因此,您的组合根(应用程序入口点,可能在 PL 项目中)将引用您的所有 DLL,或者您使用后期绑定。 【参考方案1】:首先,您可以考虑使用接口解耦层,并且可以将接口分离为单独的 dll。这样每一层就只对下一层的接口有依赖。
我也不确定为什么需要从 DAL 耦合到 BLL?这是为了回电吗?你不能改用事件吗?
假设所有 3 层都在进程中运行,并假设您的 PL 是您的应用程序的“入口点”(组合根),如果您使用 PL 中的引导代码分离出接口,IMO 通常的依赖是:
PL => 对 BLL 和 DAL(具体和接口)以及 IoC 容器的引用 BLL 引用 DAL(或仅引用接口,如果适用) DAL 无依赖关系(虽然通常会依赖 DTO / POCO / Entities)PL 可以将 IoC 配置卸载到 Bootstrapper dll,从而:
PL => 对 BLL 接口和引导程序的引用 Bootstrapper => 引用所有内容和 IoC 容器 BLL => 参考 DAL 接口 DAL => 无依赖(虽然通常会依赖 DTO/POCO/实体)对于某些容器,您可以避免通过using configuration, or convention 从引导程序引用所有 dll 的要求。但是,这些 dll 显然仍需要与您的应用一起部署。
【讨论】:
@@nonnb,您提到 DAL 在您的两个选项中都没有依赖关系。但是我做了一个 IOC,在我的 BLL 中定义了 IRepository 接口。任何必须与 BLL 一起工作的 DAL 都需要实现这些接口。逻辑是任何数据库,因此 DAL 只是 BLL 实体的存储,因此 DAL 应该依赖于 BLL,而不是相反。 事后看来,OP 可能将 Evans 风格的域模型称为 BLL,因此需要从 DAL 中引用域。另一种选择是在 DAL 中使用单独的“贫血”DTO PO[CJ]O 进行脱水/再水化。然后可以将这些映射到/来自 BLL/域模型。诸如 Automapper 之类的工具可以简化编码。然后 DAL 和 BLL 都会引用 DTO以上是关于传统的 3 层架构与 IOC 的 3 层的主要内容,如果未能解决你的问题,请参考以下文章