为什么不使用 IoC 容器来解决实体/业务对象的依赖关系?

2023-12-14

我了解 DI 背后的概念,但我只是在学习不同的 IoC 容器可以做什么。似乎大多数人都主张使用 IoC 容器来连接无状态服务,但是将它们用于实体等有状态对象呢?

无论是对还是错,我通常都会用行为填充我的实体,即使该行为需要外部类。例子:

public class Order : IOrder
{

    private string _ShipAddress;
    private IShipQuoter _ShipQuoter;

    public Order(IOrderData OrderData, IShipQuoter ShipQuoter)
    {
        // OrderData comes from a repository and has the data needed 
        // to construct order
        _ShipAddress = OrderData.ShipAddress;  // etc.
        _ShipQuoter = ShipQuoter;

    }

    private decimal GetShippingRate()
    {
        return _ShipQuoter.GetRate(this);
    }
}

如您所见,依赖项是构造函数注入的。现在有几个问题。

  1. 让您的实体依赖于外部类(例如 ShipQuoter)是否被认为是不好的做法?如果我正确理解了定义,消除这些依赖性似乎会让我走向贫血领域。

  2. 使用 IoC 容器来解决这些依赖关系并在需要时构建实体是一种不好的做法吗?是否有可能做到这一点?

感谢您的任何见解。


第一个问题是最难回答的。让实体依赖外部类是不好的做法吗?这当然不是最常见的事情。

例如,如果您将存储库注入到您的实体中,您实际上就拥有了活动记录模式。有些人喜欢这种模式是因为它提供了便利,而其他人(比如我)则认为它是一种代码味道或反模式,因为它违反了单一责任原则 (SRP).

您可能会争辩说,将其他依赖项注入实体会将您拉向相同的方向(远离 SRP)。另一方面,你肯定是正确的,如果你不这样做,那么吸引力就会转向贫血域模型.

我与这一切斗争了很长一段时间,直到我遇到了格雷格·杨(Greg Young)(已废弃)关于 DDDD 的论文他解释了原因刻板的 n 层/n 层架构将始终是 CRUDy(因此相当贫血)。

将我们的重点转移到对领域对象进行建模命令和事件而不是名词似乎使我们能够构建适当的面向对象的领域模型。

第二个问题更容易回答。您始终可以使用抽象工厂在运行时创建实例。通过 Castle Windsor,您甚至可以使用类型化工厂设施,从而减轻您手动实施工厂的负担。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么不使用 IoC 容器来解决实体/业务对象的依赖关系? 的相关文章

随机推荐

  • 如何向正则表达式添加连字符

    我遇到过这种模式 w 和来自http gskinner com RegExr 网站我明白 w 匹配字母数字字符和下划线 并且 匹配先前的标记 1 次或多次 不太确定这意味着什么 如何将连字符添加到列表中 I tried w 但这不起作用 我
  • PHP 和 Exchange Web 服务:使用 php-ews 获取消息正文

    我无法使用 php ews 从 Exchange 2010 服务器获取电子邮件的消息正文 这是我的代码 ews new ExchangeWebServices hostname username password ExchangeWebSe
  • 写入 Java 进程的 InputStream

    我有一个通过以下方式启动 java 进程 即 执行已编译的 java 代码 的代码 ProcessBuilder builder new ProcessBuilder java Sample arg1 arg2 builder redire
  • Pytesseract OCR 多个配置选项

    我在使用 pytesseract 时遇到一些问题 我需要将 Tesseract 配置为接受个位数 同时也只能接受数字 因为数字零经常与 O 混淆 像这样 target pytesseract image to string im confi
  • 迁移到 .NET 6 后找不到视图

    我将 ASP NET CORE MVC 项目从 NET Core 2 1 迁移到 NET 6 进行相关更改后 项目编译并启动看似正常 但找不到视图 根路径已设置app Environment ContentRootPath Director
  • 我在 Google Play 开发者控制台中遇到的崩溃和 ANR 错误比 Firebase Crashlytics 中的要多。这正常吗?

    过去 30 天内 我在 Firebase Crashlytics 和 Google Play 开发者控制台中看到了我的应用程序的崩溃和 ANR 错误报告 这是我所看到的 Firebase Crashlytics 总共 5 次崩溃 ANR G
  • Excel 和 C# 应用程序之间的进程间通信?

    我想知道是否有一种方法可以在 excel 实例和 C 应用程序之间建立通信 例如 当单元格值发生变化时 我想将更新后的值实时发送到 C 应用程序 提前致谢 你需要办公室主要互操作程序集 它们是 MS Office 公开的 COM API 的
  • Swift 中的泛型和函数式编程

    下面 sum 函数的两个变体是我尝试用 Swift 重复 Abelson 和 Sussman 在经典的 计算机程序的结构和解释 一书中介绍的 lisp 版本 第一个版本用于计算某个范围内的整数之和 或某个范围内的整数的平方和 第二个版本用于
  • tvOS UITextField 编辑后为空

    Editing UITextFieldtvOS 中显示了一个新视图 用户可以在其中输入文本 完成文本输入后 用户将返回到之前的视图 但是 我发现当我从文本编辑器返回时 我编辑的文本不会显示在我的文本字段中 这是怎么回事 电视操作系统版本9
  • MySQL,多行分隔字段

    我有一个 MySQL 表 其中包含如下字段和数据 PartNumber Priority SupName a1 0 One a2 0 One a2 1 Two a3 0 One a4 1 Two a5 2 Three 我正在尝试创建一个视图
  • C# 无协议 SuperSocket

    问题很简单 我已阅读全文超级插座文档 但我不明白是否有一种方法可以在不实现协议的情况下使用它 我不需要发送特定的命令 而只需发送可能是一个或数百个字节 具体取决于许多因素 我需要更新一个使用简单套接字的旧 TCP 服务器 它是我在 4 年前
  • 如何使用 webpack 混淆 js 文件

    我想在 public js 中混淆我的 js 文件 但在混淆之前 是否可以先在我的 public 文件夹外部的其他目录中传输 然后混淆的结果将在 public js 中 先感谢您 我的回答来得很晚 但我建议https obfuscator
  • 值类型何时存储在堆栈中(C#)?

    当我阅读下一本书的 值和引用类型 一章时 我想到了一个问题 值类型何时存储在堆栈中 因为程序员无法在类外初始化任何值类型 因为当我们在类中初始化一些值类型的变量时 变量就会存储在堆中 我的问题是 值类型什么时候存储在堆栈中 好吧 首先 您很
  • CMake 无法与 Google Protobuf 配合使用

    无法使用 CMake 链接 protobuf 库 我的 CMakeLists 是 cmake minimum required VERSION 3 6 project addressbook set CMAKE CXX STANDARD 1
  • 不带计数器的自定义周期函数

    我在用ode45求解一个简单的 ODE function dCdt u vent t C if t gt 600 t lt 720 Q Q2 elseif t gt 1320 t lt 1440 Q Q2 elseif t gt 2040
  • 获取日期时间之间的时间差

    如何求2次之间的差值 例子 var now 04 09 2013 15 00 00 var then 04 09 2013 14 20 30 expected result 00 39 30 I tried var now moment 0
  • JavaScript 监听器不断增加

    我实现了一个网络应用程序并使用谷歌开发人员工具监控了性能 我注意到听众不断增加 听众数量也在不断增加 听众增加的部分看起来像这样 let ival interval function http get someurl this call i
  • 使用 ffmpeg 进行转换,无需执行

    我的 Windows XP Apache PHP 5 3 和 ffmpeg 工作正常 我需要将 flv 转换为 avi 或反之亦然 而不使用exec 命令 这可能吗 谢谢 编辑 我希望有人可以编辑 ffmpeg 源代码并在 php 扩展中实
  • csh 上的自连接字符串

    我需要将 argv 中的部分内容连接到我的变量之一 我将向您展示我的代码 bin csh set stringList foreach param argv if param TEST then set stringList stringL
  • 为什么不使用 IoC 容器来解决实体/业务对象的依赖关系?

    我了解 DI 背后的概念 但我只是在学习不同的 IoC 容器可以做什么 似乎大多数人都主张使用 IoC 容器来连接无状态服务 但是将它们用于实体等有状态对象呢 无论是对还是错 我通常都会用行为填充我的实体 即使该行为需要外部类 例子 pub