.NET Core 3.1运行时加载含依赖的控制器程序集问题排查
问题:ASP.NET Core 3.1运行时加载带Microsoft.Data.SqlClient的控制器DLL失败
许久未使用.NET框架开发,如今在ASP.NET Core主机应用中无法运行时加载包含ControllerBase的DLL程序集。具体而言,当控制器DLL无依赖项时一切正常,但在该DLL中使用兼容.NET Core 3.1的Microsoft.Data.SqlClient 5.0.0执行存储过程后出现问题。
我在主机项目的Startup.cs中编写了如下代码尝试加载程序集及其依赖:
private IEnumerable<Assembly> LoadControllerAssemblies(string controllerPath) { AssemblyLoadContext.Default.Resolving += (context, name) => { string assemblyPath = $"{controllerPath}\\dep\\{name.Name}.dll"; if (assemblyPath != null) return context.LoadFromAssemblyPath(assemblyPath); return null; }; var assemblies = new List<Assembly>(); //To get the location the assembly normally resides on disk or the install directory string path = System.Reflection.Assembly.GetExecutingAssembly().CodeBase; //once you have the path you get the directory with: var directory = Path.Combine(System.IO.Path.GetDirectoryName(path), controllerPath).Replace("file:\\", @""); // Carica tutti i file DLL nella cartella specificata var dllFiles = Directory.GetFiles(directory, "*.dll"); foreach (var dllFile in dllFiles) { try { // Carica l'assembly con l'API AssemblyLoadContext var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(dllFile); assemblies.Add(assembly); } catch (Exception ex) { // _logger.LogError(ex, $"Errore durante il caricamento dell'assembly {dllFile}"); } } //var assemblyPath = Path.Combine(System.IO.Path.GetDirectoryName(path), controllerPath, "dep", "Microsoft.Data.SqlClient.dll").Replace("file:\\", @""); //var assemblyDep = AssemblyLoadContext.Default.LoadFromAssemblyPath(assemblyPath); return assemblies; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { //string path = System.Reflection.Assembly.GetExecutingAssembly().Location; services.AddHttpContextAccessor(); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0); var controllerAssemblies = LoadControllerAssemblies("Controllers"); // Registra i controller di API con il framework DI foreach (var assembly in controllerAssemblies) { services.AddMvc() .AddApplicationPart(assembly).AddControllersAsServices(); } services.AddHttpClient("apiClient", client => { client.BaseAddress = new Uri(Globals.SL_URI); }).ConfigurePrimaryHttpMessageHandler(() => { var handler = new HttpClientHandler(); handler.ServerCertificateCustomValidationCallback = (message, certificate, chain, errors) => true; return handler; }); services.AddRouting(); //services.AddHostedService<ControllerLoader>(); }
尝试多种方案均失败:
- 将Microsoft.Data.SqlClient放在依赖文件夹加载时,抛出
System.Reflection.ReflectionTypeLoadException,提示无法加载该程序集,参数错误; - 将所有依赖与控制器DLL放在同一目录时,应用可启动,但调用API时提示“Microsoft.Data.SqlClient is not supported on this platform.”;
仅有的可行方案是在主项目中引入Microsoft.Data.SqlClient依赖,但这违背了控制器模块可独立开发无需修改主项目的初衷。
请问问题出在哪里?是否与.NET Core 3.1版本有关?还有哪些可尝试的解决办法?
内容的提问来源于stack exchange,提问作者Hammeronthenet
相关产品推荐
相关产品推荐

