使用通过 ILMerge 创建的库中的程序集
Use assembly from a library which has been created through ILMerge
我已经使用工具 ILMerge 创建了一个程序集包。
有一个程序集(让我们称之为 A
),它是打包程序集的一部分,它将被另一个程序集使用,但不包含在包中(让我们称之为 B
).
现在我要做的是创建一个引用打包程序集和 B
的项目。现在我想这样做:
public void Foo()
{
var obj = new Bar(); // Bar is part of `A`
var someFactory = new Factory(); // is part of `B`
someFactory.DoSomething(obj);
// compiler error here, which says I need to reference the assembly which contains `Bar`
}
我确保包含在程序包中的程序集 A
与 B
引用的程序集相同。
我在这里遗漏了什么吗?
更新更多上下文
我们有一个数据模型项目,它有很多依赖项目(我知道这首先很糟糕,但它的遗留代码:-( ) 所以我想将所有这些程序集合并到一个中以便使用在多个解决方案中更容易组装数据模型。
B
引用 A
,而不是你编造的任何奇怪的合并程序集。它可能包含 A
的所有类型,但 不是 A
-- 程序集标识很重要。 MyMergedPackage.Bar
不是 A.Bar
,即使它们使用完全相同的类型名称直至命名空间。
有多种可能的解决方案。
首先,也是最明显的,您也可以简单地合并 B
。在典型的 ILMerge 场景中,您将 所有 程序集(包括主要可执行文件)合并到一个光荣的奇点中,因此您不会遇到这个问题。我假设您有充分的理由不这样做。
您可以简单地调用您的合并程序集 A
,即使它是 A
加上更多。如果 A
有一个强名称,您需要为合并后的程序集指定相同的名称(版本和所有)。这将使 B
保持快乐,这可能就足够了,但如果您开始添加多个想要整体的一部分的程序集(您不能简单地以不同的名称复制 A
,因为类型将不会被识别为相同)。
如果您的 .NET 版本足够新,您可以创建一个新程序集 A
,它只包含一个 type forward for Bar
到您的新程序集.这个 A
只是原始文件的占位符,分发只是为了让 B
和其他朋友开心。如果你有很多这样的类型,这就很尴尬了,你需要自动帮助。我没有立即意识到任何。在大多数情况下,它也违背了合并的目的,因为无论如何你最终都会再次得到多个程序集。
在编译时,只需使用单独的程序集。在部署时,将它们全部替换为您的合并程序集。使用 AppDomain.AssemblyResolve
的处理程序对代码进行排序,以修复 运行 时间的实际类型加载(只需将所有未知数重定向到合并的程序集)。这可能需要一些仔细的修补以确保事件在 之前 触发 运行 时间需要查找任何引用的程序集(静态构造函数在这里尤其会破坏你的乐趣)。 =29=]
免责声明:我已经完全测试了 none 这些解决方案;如果一个不起作用,请告诉我,以便我可以解决这个问题。
我已经使用工具 ILMerge 创建了一个程序集包。
有一个程序集(让我们称之为 A
),它是打包程序集的一部分,它将被另一个程序集使用,但不包含在包中(让我们称之为 B
).
现在我要做的是创建一个引用打包程序集和 B
的项目。现在我想这样做:
public void Foo()
{
var obj = new Bar(); // Bar is part of `A`
var someFactory = new Factory(); // is part of `B`
someFactory.DoSomething(obj);
// compiler error here, which says I need to reference the assembly which contains `Bar`
}
我确保包含在程序包中的程序集 A
与 B
引用的程序集相同。
我在这里遗漏了什么吗?
更新更多上下文
我们有一个数据模型项目,它有很多依赖项目(我知道这首先很糟糕,但它的遗留代码:-( ) 所以我想将所有这些程序集合并到一个中以便使用在多个解决方案中更容易组装数据模型。
B
引用 A
,而不是你编造的任何奇怪的合并程序集。它可能包含 A
的所有类型,但 不是 A
-- 程序集标识很重要。 MyMergedPackage.Bar
不是 A.Bar
,即使它们使用完全相同的类型名称直至命名空间。
有多种可能的解决方案。
首先,也是最明显的,您也可以简单地合并
B
。在典型的 ILMerge 场景中,您将 所有 程序集(包括主要可执行文件)合并到一个光荣的奇点中,因此您不会遇到这个问题。我假设您有充分的理由不这样做。您可以简单地调用您的合并程序集
A
,即使它是A
加上更多。如果A
有一个强名称,您需要为合并后的程序集指定相同的名称(版本和所有)。这将使B
保持快乐,这可能就足够了,但如果您开始添加多个想要整体的一部分的程序集(您不能简单地以不同的名称复制A
,因为类型将不会被识别为相同)。如果您的 .NET 版本足够新,您可以创建一个新程序集
A
,它只包含一个 type forward forBar
到您的新程序集.这个A
只是原始文件的占位符,分发只是为了让B
和其他朋友开心。如果你有很多这样的类型,这就很尴尬了,你需要自动帮助。我没有立即意识到任何。在大多数情况下,它也违背了合并的目的,因为无论如何你最终都会再次得到多个程序集。在编译时,只需使用单独的程序集。在部署时,将它们全部替换为您的合并程序集。使用
AppDomain.AssemblyResolve
的处理程序对代码进行排序,以修复 运行 时间的实际类型加载(只需将所有未知数重定向到合并的程序集)。这可能需要一些仔细的修补以确保事件在 之前 触发 运行 时间需要查找任何引用的程序集(静态构造函数在这里尤其会破坏你的乐趣)。 =29=]
免责声明:我已经完全测试了 none 这些解决方案;如果一个不起作用,请告诉我,以便我可以解决这个问题。