使用ILRepack.MSBuild.Task合并程序集后无法访问合并类的问题排查
问题:合并.NET程序集后无法访问内部公共类
我使用ILRepack工具合并多个.NET程序集,在名为MyCombinedClassLibrary的类库中引用了NuGet包ILRepack.MSBuild.Task(版本2.0.13),构建后成功将MyClassLibrary1、MyClassLibrary2、MyClassLibrary3合并为MyCombinedClassLibrary.dll。但在MSTest等项目中引用该合并程序集时,无法访问如MyClassLibrary1.MyClass这类合并后的公共类——已通过dotPeek确认合并后的dll确实包含这些类,不清楚问题根源。
MyCombinedClassLibrary.csproj配置如下:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net8.0</TargetFramework> <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <!-- PACKAGE REFERENCES --> <ItemGroup> <PackageReference Include="ILRepack.MSBuild.Task" Version="2.0.13" /> </ItemGroup> <!-- ILREPACK CONFIGURATION --> <Target Name="ILRepack" AfterTargets="Build" Condition='$(Configuration) == "Release"'> <PropertyGroup> <WorkingDirectory>$(MSBuildThisFileDirectory)bin\$(Configuration)</WorkingDirectory> </PropertyGroup> <ItemGroup> <InputAssemblies Include="MyClassLibrary1.dll" /> <InputAssemblies Include="MyClassLibrary2.dll" /> <InputAssemblies Include="MyClassLibrary3.dll" /> </ItemGroup> <ItemGroup> <InternalizeExcludeAssemblies Include="MyClassLibrary1" /> <InternalizeExcludeAssemblies Include="MyClassLibrary2" /> <InternalizeExcludeAssemblies Include="MyClassLibrary3" /> </ItemGroup> <Message Text="MERGING: @(InputAssemblies->'%(Filename)') into $(AssemblyName)" Importance="High" /> <ILRepack OutputType="$(OutputType)" MainAssembly="$(AssemblyName).dll" OutputAssembly="$(AssemblyName).dll" InputAssemblies="@(InputAssemblies)" InternalizeExcludeAssemblies="@(InternalizeExcludeAssemblies)" WorkingDirectory="$(WorkingDirectory)" /> </Target> </Project>
排查与解决方案
- 确认引用的是合并后的dll:测试项目不要直接引用MyCombinedClassLibrary项目,改为手动引用
bin/Release目录下的合并后dll。如果是项目引用,构建时可能优先使用主程序集的原始输出(空壳dll)而非合并后的版本。 - 禁用Internalize内部化:ILRepack默认会将非主程序集的类型标记为内部,即使配置了
InternalizeExcludeAssemblies也可能存在匹配问题。直接在ILRepack任务中添加Internalize="false"属性,完全关闭内部化:<ILRepack OutputType="$(OutputType)" MainAssembly="$(AssemblyName).dll" OutputAssembly="$(AssemblyName).dll" InputAssemblies="@(InputAssemblies)" Internalize="false" WorkingDirectory="$(WorkingDirectory)" /> - 为主程序集添加公共类型:如果MyCombinedClassLibrary本身没有任何公共类,编译器可能无法正确识别合并进来的类型。在主程序集中添加一个空的公共类,比如:
namespace MyCombinedClassLibrary; public class DummyClass {} - 清理缓存后重建:删除所有项目的
bin和obj目录,重新构建合并项目和测试项目,避免旧的未合并dll被缓存引用。 - 检查命名空间引用:确认测试项目中已添加目标类的命名空间引用,比如
using MyClassLibrary1;,同时排查是否存在命名空间冲突。
内容的提问来源于stack exchange,提问作者murphysto
相关产品推荐
相关产品推荐

