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

.NET Core MVC API模块化开发:NuGet插件容器加载问题咨询

解决.NET Core MVC API中加载全局NuGet包插件的问题

我之前在迁移传统.NET的MEF插件到.NET Core时也踩过这个坑,全局NuGet缓存的路径确实和之前解决方案目录里的不一样,给你几个实用的解决思路:

一、换用.NET Core原生的AssemblyLoadContext加载插件(推荐)

MEF在.NET Core里虽然能用,但原生的AssemblyLoadContext对插件隔离和加载控制更友好,用来替代MEF挺合适的。

1. 先找到全局NuGet缓存的位置

全局NuGet缓存的默认路径是固定的:

  • Windows:%userprofile%\.nuget\packages
  • macOS/Linux:~/.nuget/packages

你可以用代码动态获取这个路径,再拼上你的插件包具体路径(比如包名MyPlugin,版本1.0.0,目标框架net6.0):

// 获取全局NuGet缓存根路径
var nugetRoot = Environment.GetEnvironmentVariable("USERPROFILE") 
                ?? Environment.GetEnvironmentVariable("HOME");
var nugetCachePath = Path.Combine(nugetRoot, ".nuget", "packages");

// 拼接插件DLL的完整路径
var pluginDllPath = Path.Combine(nugetCachePath, "myplugin", "1.0.0", "lib", "net6.0", "MyPlugin.dll");

2. 用AssemblyLoadContext加载并实例化插件

// 创建独立的加载上下文,isCollectible设为true方便后续卸载插件
var pluginLoadContext = new AssemblyLoadContext("MyPluginLoadContext", isCollectible: true);
try
{
    // 加载插件程序集
    var pluginAssembly = pluginLoadContext.LoadFromAssemblyPath(pluginDllPath);
    
    // 查找实现了你定义的插件接口的类型
    var pluginType = pluginAssembly.GetTypes()
        .FirstOrDefault(t => typeof(IYourPluginInterface).IsAssignableFrom(t) && !t.IsAbstract);
    
    if (pluginType != null)
    {
        // 实例化插件,之后可以注册到DI容器或者直接使用
        var pluginInstance = Activator.CreateInstance(pluginType) as IYourPluginInterface;
    }
}
finally
{
    // 如果需要动态卸载插件,调用这个方法(仅当isCollectible为true时生效)
    // pluginLoadContext.Unload();
}

二、让插件DLL自动复制到项目输出目录

如果不想直接读取全局缓存,你可以修改API项目的.csproj文件,配置NuGet包将插件DLL复制到输出目录,这样加载起来更省心:

<ItemGroup>
  <PackageReference Include="MyPlugin" Version="1.0.0">
    <!-- 配置让DLL复制到输出目录 -->
    <PrivateAssets>all</PrivateAssets>
    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
  </PackageReference>
</ItemGroup>

之后直接从项目的输出目录加载插件:

var pluginDllPath = Path.Combine(AppContext.BaseDirectory, "MyPlugin.dll");
// 后续加载逻辑和上面一样

三、继续用MEF在.NET Core中加载插件

如果你习惯了MEF的用法,也可以继续用,只需要调整一下程序集的搜索路径:

  1. 先安装两个NuGet包:System.Composition和System.Composition.Hosting
  2. 配置MEF容器时,指定全局NuGet包中插件DLL所在的目录:
// 插件DLL所在的目录,比如全局缓存里的lib/net6.0路径
var pluginDir = Path.Combine(nugetCachePath, "myplugin", "1.0.0", "lib", "net6.0");

var containerConfig = new ContainerConfiguration()
    .WithAssembly(Assembly.GetExecutingAssembly())
    .WithAssembliesInPath(pluginDir);

using var mefContainer = containerConfig.CreateContainer();
// 获取所有实现了接口的插件实例
var plugins = mefContainer.GetExports<IYourPluginInterface>();

几个需要注意的点

  • 确保插件包的目标框架和你的API项目完全一致(比如都是net6.0),不然会加载失败。
  • 如果插件有依赖项,AssemblyLoadContext会自动从应用程序基目录或NuGet缓存里找,但如果依赖项不在这些位置,得手动指定依赖路径。
  • 生产环境里,建议把插件包复制到专门的插件目录(不要直接读全局缓存),避免缓存被清理或者包版本变更导致服务出问题。

内容的提问来源于stack exchange,提问作者user5954882

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:11:24