想象一下场景,A.dll和B.dll,A.dll引用B.dll并调用驻留在B.dll中的方法。
在未来的某个时刻,你有两个不同版本的A.dll和B.dll(为什么会出现这种情况并不重要)。您希望能够在同一个应用程序中使用这些dll的两个版本。
我遇到的问题是我可以加载Av1.dll和Av2.dll但他们最终都使用Bv1.dll。
所以我想要的是:
Av1.dll --> Bv1.dll
Av2.dll --> Bv2.dll
但正如我所说,我最终得到的是:
Av1.dll --> Bv1.dll
Av2.dll --> Bv1.dll
AppDomains不可行,因为每个输入和输出都需要实现MarshalByRefObject,因此它们最终变得难以操作。
即使他们有点古怪,我也会接受创造性的解决方案。这更像是一个学术问题,所以不要因为重构你在现实世界中需要做的dll或一些软糖而陷入困境,将其视为挑战。
有可能吗?就像你可以在幕后动态检查,重写和重新编译dll,但是替换引用,实际上是:
A.dll --> B.dll
C.dll --> D.dll
正如我所说,我对创造性解决方案持开放态度。
修改
好的,也许一个更清晰的例子会有所帮助。
让我们想象一下,第三方为您提供了计算所得税的图书馆。该库由相互引用的dll组成。
所以在正常情况下你有:
TaxHelper helper = new TaxHelper();
var result = helper.CalculateIncomeTax(...params...);
但是,让我们想象,在下一个纳税年度,您的第三方会为您提供新版本的图书馆,因为新税务年度的规则已经更改,但您还必须能够计算税额。往年。他们所做的就是更改代码并重新编译,所有类和dll名称都是相同的。
所以我一直在尝试的是沿着这些方向发展的事情(这只是我的头脑,所以可能不是100%正确):
Assembly taxHelper1Assembly = Assembly.LoadFrom(...path1...);
Assembly taxHelper2Assembly = Assembly.LoadFrom(...path2...);
Type taxHelper1Type = taxHelper1Assembly.GetType(...);
Type taxHelper2Type = taxHelper2Assembly.GetType(...);
dynamic taxHelper1 = Activator.CreateInstance(taxHelper1Type);
dynamic taxHelper2 = Activator.CreateInstance(taxHelper2Type);
var result1 = taxHelper1.CalculateIncomeTax(...params...);
var result2 = taxHelper2.CalculateIncomeTax(...params...);
现在这可行,直到某一点,taxHelper1
和taxHelper2
都是不同的版本,并会返回不同的结果......但是......虽然顶级TaxHelper类不同,但在内部他们引用其他dll作为依赖项,taxHelper1
引用了正确的依赖项,因为它们是先加载的,taxHelper2
还引用了taxHelper1
个依赖项。
修改2
想想我在这个帖子中找到了答案:Loading Dependent Assemblies Manually
答案 0 :(得分:0)
在这里,这可能足以让你入门。它被称为依赖注入,正如您在问题的评论中提到的那样。你应该读一读。
这里我在A.dll中定义了两种类型。其中一个是定义B
的合同的接口:
public interface IDependencyB
{
string Name { get; }
}
这是我的A
课程。它的构造函数需要IDependencyB
:
public class A
{
public A(IDependencyB dependencyB)
{
System.Diagnostics.Debug.Print(dependencyB.Name);
}
}
然后,您可以在单独的程序集中定义两个(或多个)类的变体,如果您愿意,可以实现该接口:
class B1 : IDependencyB
{
public string Name => "B1";
}
class B2 : IDependencyB
{
public string Name => "B2";
}
你可以这样测试:
var b1 = new B1();
var b2 = new B2();
var a1 = new A(b1);
var a2 = new A(b2);
这是一个非常基本的例子,但我认为它应该让你朝着正确的方向前进。