6

我希望这里缺少一些简单的东西。我正在尝试维护两个独立的项目

ProjectName.Core &
ProjectName.Infrastructure

这是在典型的 Onion 架构中创建的,因此我可以松散地耦合我的服务并获得更大的灵活性。基础设施项目引用核心项目。编译后,它们会生成这些 DLL

ProjectName.Core.dll &
ProjectName.Infrastructure.dll

但我想让它只生成 1 个 dll。

ProjectName.Infrastructure.dll (or even ProjectName.dll)

我曾尝试使用 ILMerge 来执行此操作,但由于基础设施引用 Core,它会引发异常,因为它找不到 Core dll。它显然不是在寻找自身。

现在我需要维护单独的项目,因为我有一些其他组合引用 Core 和另一个将连接在一起的项目,例如

ProjectName.Core &
ProjectName.DataAccess &
ProjectName.Web

编辑:我当前的解决方案使用 Nant 构建脚本调用 ILMerge。它成功地合并在一起。但是当我尝试使用合并的 DLL 时,它会抛出异常,因为它找不到核心库。

  <target name="merge.core">
    <property name="temp.dir" value="${build.dir}\Temp\"/>
    <mkdir dir="${temp.dir}" if="${not directory::exists(temp.dir)}"/>
    <property name="tools.dir" value="&quot;${directory::get-current-directory()}\Tools\&quot;"/>
    <exec program="Tools\ILMerge\ILMerge.exe" workingdir=".">
      <arg value="/t:Library"/>
      <arg value="/ndebug"/>      
      <arg value="/out:&quot;${build.dir}\Temp\ProjectName.Infrastructure.dll&quot;"/>
      <arg value="&quot;${build.dir}ProjectName.Core.dll&quot;"/>
      <arg value="&quot;${build.dir}Xceed.Compression.dll&quot;"/>
      <arg value="&quot;${build.dir}ProjectName.Infrastructure.dll&quot;"/>
      <arg value="&quot;${build.dir}ProjectName.Infrastructure.XmlSerializers.dll&quot;"/>
    </exec>
    <delete file="${build.dir}ProjectName.Core.dll"/>
    <delete file="${build.dir}Xceed.Compression.dll"/>
    <delete file="${build.dir}ProjectName.Infrastructure.dll"/>
    <delete file="${build.dir}ProjectName.Infrastructure.XmlSerializers.dll"/>
    <move file="${build.dir}\Temp\ProjectName.Infrastructure.dll" tofile="${build.dir}ProjectName.Infrastructure.dll"/>
    <delete dir="${temp.dir}" if="${directory::exists(temp.dir)}"/>
  </target>

要清楚一点。我可以使用核心库之外的对象,但不能使用基础设施库。因为一旦尝试实例化这些对象之一,.NET 似乎会尝试加载依赖项但找不到它。

4

4 回答 4

4

使用ILMerge。它可以开箱即用地做到这一点。

于 2009-07-15T04:44:29.403 回答
2

合并!几乎和切片面包一样好。

http://research.microsoft.com/en-us/people/mbarnett/ilmerge.aspx

于 2009-07-15T04:47:00.147 回答
1

据我所知,这在 Visual Studio 中是不可能的,但您可以将每个项目编译为 netmodule,然后将它们作为 DLL 连接在一起。像这样编译:

csc misource1.cs misource2.cs misource3.cs /target:module

然后与 al.exe 工具链接在一起,请参阅.netmodule Files as Linker InputC# Assemblies

于 2009-07-15T04:41:18.067 回答
0

最新版本的 ILMerge 有一个/closed选项可用于合并程序集的传递闭包。它解决了这个确切的问题(参见章节2.6 Closed4.1 Input assembly not merged in correctlyILMerge.doc 用户手册)。

请注意,如果您的库尝试从命名程序集动态加载对象,那么它将无法工作,因为合并的程序集名称与原始程序集名称不同。在这种情况下,ILMerge 无能为力。你必须修改你的依赖注入来解决这个问题。

于 2010-09-16T17:05:17.487 回答