解耦实现问题:.NET项目类库间接引用失败报错求解
错误原因
- 运行时依赖缺失:C项目仅引用了B类库,默认编译时只会把B的dll复制到C的输出目录,而B的工厂方法返回的是A中定义的
MathOperations类型,运行时CLR需要加载A的程序集MathLibrary.dll却找不到,就会触发程序集加载失败异常。 - 解耦逻辑失效:当前设计并没有真正实现A和C的解耦,B的工厂方法直接返回A的具体类,C调用
ADD方法依然强依赖A中的MathOperations类定义,只是把直接引用改成了间接依赖而已。
解决方案
方案1:快速修复运行报错(不调整解耦逻辑)
- 直接在C项目中添加对A类库
MathLibrary.dll的引用,编译时会自动把A的dll复制到输出目录,即可正常运行。 - 或在B类库的生成配置中,设置将引用的A的dll复制到输出目录,同时在C项目的生成事件中添加命令,把B输出目录里的A的dll复制到C的输出目录。
方案2:调整架构实现真正的A、C解耦
- 新增公共接口类库,定义运算规范:
Public Interface IMathOperations Function ADD(ByVal a As Integer, ByVal b As Integer) As Integer End Interface
- 修改A类库的
MathOperations类实现该接口:
Imports 公共接口类库命名空间 Public Class MathOperations Implements IMathOperations Function ADD(ByVal a As Integer, ByVal b As Integer) As Integer Implements IMathOperations.ADD Return (a + b) End Function End Class
- 修改B类库的工厂方法返回接口类型,B仅需要引用接口类库和A类库:
Imports MathLibrary Imports 公共接口类库命名空间 Public Class Factory Shared Function createMathsObject() As IMathOperations Return New MathOperations() End Function End Class
- C项目仅需要引用B类库和接口类库,不需要引用A类库,修改C的代码:
Imports FactoryMathsLibrary Imports 公共接口类库命名空间 Module Module1 Sub Main() Dim a, b As Integer Dim m As IMathOperations = Factory.createMathsObject() Console.Write("Enter 1st value: ") a = Integer.Parse(Console.ReadLine()) Console.Write("Enter 2nd value: ") b = Integer.Parse(Console.ReadLine()) Console.WriteLine("a + b = {0}", m.ADD(a, b)) Console.ReadLine() End Sub End Module
该方案下C完全不依赖A的具体实现,只依赖接口定义,后续如果要替换A的运算实现,仅需要修改B的工厂逻辑,不需要调整C的代码,真正实现解耦。
内容的提问来源于stack exchange,提问作者Sougata
相关产品推荐
相关产品推荐

