作者:zvan | 来源:互联网 | 2023-02-01 12:03
我试图动态加载包含ASP.NET Core Startup
类的.NET Core DLL .然后我想实例化Startup
该类并将其交给TestHost
API,因此我可以在内存中启动该站点.我写了以下代码:
var directoryPath = @"C:\Dlls";
var assemblyFilePath = Path.Combine(directoryPath, "Foo.dll");
var assemblyName = AssemblyLoadContext.GetAssemblyName(assemblyFilePath);
var assembly = new AssemblyLoader(directoryPath).LoadFromAssemblyName(assemblyName);
var startupType = assembly.ExportedTypes
.FirstOrDefault(x => string.Equals(x.Name, "Startup"));
var webHostBuilder = new WebHostBuilder()
.UseStartup(startupType)
.UseUrls(new string[] { "http://localhost" });
using (var testServer = new TestServer(webHostBuilder))
{
var respOnse= testServer.CreateClient().GetAsync("/");
}
public class AssemblyLoader : AssemblyLoadContext
{
private readonly string directoryPath;
public AssemblyLoader(string directoryPath) =>
this.directoryPath = directoryPath;
protected override Assembly Load(AssemblyName assemblyName)
{
var dependencyCOntext= DependencyContext.Default;
var compilatiOnLibraries= dependencyContext
.CompileLibraries
.Where(x => x.Name.Contains(assemblyName.Name))
.ToList();
if (compilationLibraries.Count > 0)
{
return Assembly.Load(new AssemblyName(compilationLibraries.First().Name));
}
else
{
var file = new FileInfo($"{this.directoryPath}{Path.DirectorySeparatorChar}{assemblyName.Name}.dll");
if (File.Exists(file.FullName))
{
var asemblyLoader = new AssemblyLoader(file.DirectoryName);
return asemblyLoader.LoadFromAssemblyPath(file.FullName);
}
}
return Assembly.Load(assemblyName);
}
}
然而,这将引发一个TypeLoadException
时assembly.ExportedTypes
被调用.完整堆栈跟踪:
发生System.TypeLoadException HResult = 0x80131522
Message =方法'Foo.Startup'中的方法'ConfigureServices'来自程序集'Foo,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'没有实现.Source = StackTrace:System.Reflection.RuntimeAssembly上的System.Reflection.RuntimeAssembly.GetExportedTypes(RuntimeAssembly assembly,ObjectHandleOnStack retTypes).GetExportedTypes()
我认为加载ASP.NET Core和其他第三方DLL(如Newtonsoft.Json)时遇到问题.