跨程序集和命名空间的依赖注入

2024-05-01

我正在解决一个 DI 问题,我认为我了解其原因,但我需要一些建议来解决。

我构建了一个与 Sql 对话的独立程序集(将此程序集称为 a),以及另一个包含业务逻辑的程序集(将此程序集称为 b)。我在 b 程序集中为 db 类创建了一个接口。由于该接口不是数据库程序集的一部分,因此我不需要对数据库项目的任何引用,并且如果我想在运行时运行单元测试而不是程序集,我可以加载对数据库程序集或存根的引用需要了解对方。

我可以在业务逻辑库中编写代码进行编译,如下所示:(假设 a 和 b 是各自程序集中的命名空间)

 a.IDatabaseClass db_class = (a.IDatabase)new b.Database();

然而,当我尝试运行它时,我收到无效的强制转换异常。我认为它可以编译,因为接口与类完美匹配,但在运行时失败,因为对象签名在数据库类的继承链中看不到 IDatabase。

在 C++ 中,您可以随心所欲地进行任何类型的转换,但 C# 对于对象指针的转换要严格一些。即使该类具有所有正确的函数签名,它也会因为对象不匹配而崩溃。

现在我可以将数据库对象接口与数据库对象一起放入程序集中,但随后业务逻辑需要对数据库程序集的引用。另外,这只会在以后造成复杂性,因为如果我在单元测试中编写存根数据库对象,我需要对数据库程序集的引用,以用于我将在测试存根对象中使用的接口。这似乎并没有通过这样做来解开耦合......

我可以将所有接口放在第三个程序集中,该程序集是数据库程序集、业务逻辑和单元测试的父程序集。这就是解决循环依赖问题的方法。然而,这将数据库程序集与父程序集联系起来,并使其与其他项目一起使用时的模块化程度大大降低。

我愿意接受有关如何设置每个程序集的建议,以便它们独立运行并可用于 DI。我想我可以将测试存根对象保留在与真实代码相同的程序集中,但这看起来很奇怪。

解决方案

下面的回复之一评论说我拍摄的内容基本上是界面的鸭子类型。 C# 当前不支持鸭子类型,但我认为这可能是可能的,因为接口实现的行为方式类似于您可能称之为的部分类指针(或者更准确地说,函数指针的集合)。我的实验告诉我情况并非如此,这就是原因。

因此,在 Redmond 将“更多野鸭”放入 C# 之前,看起来我们无法达到完全解耦程序集的最终优雅水平。


创建一个包含常用接口的参考库。这样,您将拥有一个包含所有与实现无关的逻辑的公共源。

我没有经验来自信地做出这样的明确陈述,但我强烈怀疑,当您谈论引用特定接口的单个​​类型及其行为方式时,耦合主要是一个问题。程序集不具有那种会使耦合成为问题的特殊性。

Edit 1

让我修改和扩展。一个程序集必须引用另一个程序集,或者两者都必须引用同一个程序集。 C# 没有鸭子接口(如果有的话)。

现在我认为最佳实践是将业务逻辑与外部接口隔离,因此如果您要执行任何操作,则应该将业务逻辑与数据库实现隔离。因此,数据库/应用程序程序集引用业务逻辑,但反之则不然。

这是有关依赖方向的更多信息 http://tpierrain.blogspot.ca/2013/08/a-zoom-on-hexagonalcleanonion.html.

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

跨程序集和命名空间的依赖注入 的相关文章

随机推荐