.NET Core中如何替代BuildManager.AddReferencedAssembly实现动态程序集引用?
我之前在把.NET Framework的插件系统迁移到.NET Core时也碰到过这个问题,确实BuildManager.AddReferencedAssembly在.NET Core里被移除了,但咱们有更灵活的方式来实现动态加载程序集及其依赖,主要有这几种方案:
.NET Core 动态加载程序集及依赖的解决方案
1. 使用 AssemblyLoadContext(推荐)
AssemblyLoadContext 是.NET Core及以后版本专门用来管理程序集加载的核心类,它能提供程序集隔离,避免和主应用的依赖冲突,还能自动处理依赖解析。
步骤:
- 首先创建一个自定义的加载上下文,用来处理插件(联系人Web API)及其依赖的加载:
public class PluginLoadContext : AssemblyLoadContext { private readonly AssemblyDependencyResolver _resolver; public PluginLoadContext(string pluginPath) : base(isCollectible: true) { // 传入插件程序集的路径,自动解析依赖 _resolver = new AssemblyDependencyResolver(pluginPath); } protected override Assembly? Load(AssemblyName assemblyName) { // 解析依赖程序集的路径 string? assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName); if (assemblyPath != null) { return LoadFromAssemblyPath(assemblyPath); } // 如果解析不到,返回null让默认上下文处理 return null; } protected override IntPtr LoadUnmanagedDll(string unmanagedDllName) { // 处理非托管依赖(如果有的话) string? libraryPath = _resolver.ResolveUnmanagedDllToPath(unmanagedDllName); if (libraryPath != null) { return LoadUnmanagedDllFromPath(libraryPath); } return IntPtr.Zero; } }
- 然后用这个上下文加载你的联系人Web API程序集,它会自动加载关联的实体、层等依赖程序集:
// 替换成你联系人Web API程序集的实际路径 var contactApiPath = @"C:\Plugins\ContactWebApi.dll"; var loadContext = new PluginLoadContext(contactApiPath); Assembly contactApiAssembly = loadContext.LoadFromAssemblyPath(contactApiPath); // (可选)如果需要显式加载某些依赖,可以遍历程序集的引用 foreach (var referencedAssembly in contactApiAssembly.GetReferencedAssemblies()) { loadContext.LoadFromAssemblyName(referencedAssembly); }
2. 直接加载程序集(简单场景)
如果你的场景比较简单,不需要程序集隔离,也可以直接用Assembly.LoadFrom或Assembly.Load来加载,然后手动处理依赖:
// 加载联系人Web API程序集 Assembly contactAssembly = Assembly.LoadFrom(@"C:\Plugins\ContactWebApi.dll"); // 加载所有关联的依赖程序集 foreach (var referencedAssembly in contactAssembly.GetReferencedAssemblies()) { Assembly.Load(referencedAssembly); }
不过这种方式会把程序集加载到默认的加载上下文里,容易出现版本冲突,所以只推荐在依赖简单的场景使用。
3. 让ASP.NET Core识别动态加载的API控制器
加载完程序集后,还要让ASP.NET Core的路由系统识别到联系人Web API里的控制器,需要在Program.cs(或Startup.cs)里配置:
var builder = WebApplication.CreateBuilder(args); // ... 其他服务配置 // 添加动态加载的程序集作为应用部件 builder.Services.AddControllers() .AddApplicationPart(contactApiAssembly) .AddControllersAsServices(); var app = builder.Build(); // ... 中间件配置
这样动态加载的API控制器就能被正常路由和调用了。
内容的提问来源于stack exchange,提问作者user8564782
相关产品推荐
相关产品推荐

