我正在尝试动态加载包含 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);
}
}
但是,这会在调用assembly.ExportedTypes
时引发TypeLoadException
。全栈跟踪:
System.TypeLoadException 發生 HResult=0x80131522
消息=程序集中类型"Foo.Startup"中的"配置服务"方法 "Foo, version=1.0.0.0, 区域性=中性, 公钥令牌=null" 不会 有一个实现。 源= 堆栈跟踪:在 System.Reflection.RuntimeAssembly.GetExportedTypes(RuntimeAssembly assembly, ObjectHandleOnStack retTypes( at System.Reflection.RuntimeAssembly.GetExportedTypes((
我认为它在加载 ASP.NET Core和其他第三方DLL(如Newtonsoft.Json(时遇到问题。
我对这个答案不满意,我会发布它,以防它对某人有帮助。
我正在执行dotnet publish
,然后尝试从已发布的输出运行我的应用程序。我设法通过使用以下命令发布一个独立的应用程序来让它工作:
dotnet publish --self-contained --framework netcoreapp1.1 --runtime win7-x64
独立应用包含运行应用所需的所有程序集,包括 .NET Core 运行时。我想避免这样做,因为它要求您事先知道运行时标识符 (RID( 以及您正在运行的平台。
鉴于知道我上面的代码缺少 .NET Core 运行时程序集,我尝试从 .NET Core 运行时文件夹加载程序集,但到目前为止这对我来说失败了。