You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将NuGet包嵌入公共类库DLL,避免客户端重复安装依赖?

可行方案(原生实现,无需外部工具)

方案1:嵌入依赖并通过AssemblyResolve加载(生成单个DLL)

这是原生实现单DLL合并的核心方法,步骤如下:

  1. 配置依赖项嵌入规则
    在公共类库的.csproj文件中,对每个需要嵌入的NuGet依赖添加如下配置,确保依赖不会传递给客户端,同时被打包为嵌入资源:

    <ItemGroup>
      <!-- 示例配置Newtonsoft.Json -->
      <PackageReference Include="Newtonsoft.Json" Version="13.0.3">
        <PrivateAssets>all</PrivateAssets>
        <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      </PackageReference>
      <!-- 其他依赖项重复上述配置 -->
    </ItemGroup>
    
    <!-- 将依赖DLL嵌入为资源 -->
    <ItemGroup>
      <EmbeddedResource Include="$(OutputPath)\Newtonsoft.Json.dll">
        <LogicalName>Newtonsoft.Json.dll</LogicalName>
      </EmbeddedResource>
      <!-- 其他依赖DLL同理添加 -->
    </ItemGroup>
    

    注:$(OutputPath)为项目输出目录,若路径不符可手动指定NuGet包内的DLL路径(如..\packages\Newtonsoft.Json.13.0.3\lib\net6.0\Newtonsoft.Json.dll)。

  2. 添加自动加载逻辑
    在公共类库中添加静态初始化类,通过AssemblyResolve事件捕获CLR的依赖加载请求,从嵌入资源中读取并加载依赖:

    using System;
    using System.Reflection;
    
    namespace YourCommonLibrary
    {
        public static class LibraryBootstrapper
        {
            static LibraryBootstrapper()
            {
                AppDomain.CurrentDomain.AssemblyResolve += ResolveEmbeddedAssembly;
            }
    
            private static Assembly? ResolveEmbeddedAssembly(object sender, ResolveEventArgs args)
            {
                var assemblyFileName = new AssemblyName(args.Name).Name + ".dll";
                var resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(assemblyFileName);
                if (resourceStream == null) return null;
    
                using (resourceStream)
                {
                    var assemblyBytes = new byte[resourceStream.Length];
                    resourceStream.Read(assemblyBytes, 0, assemblyBytes.Length);
                    return Assembly.Load(assemblyBytes);
                }
            }
        }
    }
    

    客户端仅需引用你的公共类库DLL,无需安装任何依赖,依赖会在运行时自动从嵌入资源加载。

方案2:打包为包含所有依赖的NuGet包(客户端一键引用)

如果允许生成NuGet包而非单DLL,这是最符合.NET生态的简洁方案:

  1. 配置项目打包属性
    在公共类库的.csproj中添加以下配置,将依赖项打包到NuGet包内,客户端安装时自动复制所有依赖到输出目录:
    <PropertyGroup>
      <PackageId>Your.Common.Library</PackageId>
      <Version>1.0.0</Version>
      <Authors>YourName</Authors>
      <Description>内置所有依赖的公共类库</Description>
      <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
      <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
    </PropertyGroup>
    
    <ItemGroup>
      <!-- 标记依赖为私有资产,不传递给客户端项目 -->
      <PackageReference Include="Newtonsoft.Json" Version="13.0.3">
        <PrivateAssets>all</PrivateAssets>
      </PackageReference>
      <!-- 其他依赖项重复上述配置 -->
    </ItemGroup>
    
  2. 打包分发
    构建项目后,bin\Release目录会生成.nupkg文件。客户端只需通过NuGet安装该包,所有依赖DLL会自动同步到输出目录,无需手动安装任何依赖包。

方案3:手动同步依赖到输出目录(生成多个独立DLL)

若不需要单DLL,仅需避免客户端手动安装NuGet依赖,可采用此方案:

  1. 配置依赖自动复制
    在公共类库的.csproj中设置依赖项复制到输出目录:
    <ItemGroup>
      <PackageReference Include="Newtonsoft.Json" Version="13.0.3">
        <PrivateAssets>all</PrivateAssets>
        <CopyLocal>true</CopyLocal>
      </PackageReference>
      <!-- 其他依赖项重复上述配置 -->
    </ItemGroup>
    
  2. 分发完整DLL集合
    构建后,将输出目录下的所有DLL(你的类库+所有依赖DLL)一起分发给客户端。客户端只需引用你的主DLL,其余依赖DLL放在同一目录下即可自动加载,无需安装NuGet包。

注意事项

  • 若依赖为强命名DLL,嵌入加载时需确保签名兼容,可选择使用同一密钥签名,或禁用依赖的强命名(若允许)。
  • 方案1需覆盖所有直接和间接依赖,可通过查看项目输出目录确认需要嵌入的DLL清单。
  • 方案2的NuGet包方式是最推荐的,既符合.NET包管理规范,又能最大程度简化客户端操作。

内容的提问来源于stack exchange,提问作者Miguel Mesquita Alfaiate

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 22:00:22