Динамическая загрузка базовой сборки ASP.NET
Я пытаюсь динамически загрузить.NET Core DLL, содержащую ASP.NET Core Startup
учебный класс. Затем я хочу создать экземпляр 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
Сообщение = метод 'ConfigureServices' в типе 'Foo.Startup' из сборки 'Foo, версия =1.0.0.0, Culture= нейтральный, PublicKeyToken=null' не имеет реализации. Source= StackTrace: at System.Reflection.RuntimeAssembly.GetExportedTypes(сборка RuntimeAssembly, ObjectHandleOnStack retTypes) в System.Reflection.RuntimeAssembly.GetExportedTypes()
Я думаю, что у него проблемы с загрузкой ядра ASP.NET и других сторонних DLL, таких как Newtonsoft.Json.
1 ответ
Я не доволен этим ответом, я его опубликую, если кому-то это поможет.
Я делал dotnet publish
а затем пытается запустить мое приложение из опубликованного вывода. Мне удалось заставить его работать, опубликовав автономное приложение, используя следующую команду:
dotnet publish --self-contained --framework netcoreapp1.1 --runtime win7-x64
Автономное приложение содержит все сборки, необходимые для запуска приложения, включая среду выполнения.NET Core. Я хотел избежать этого, поскольку он требует от вас знать идентификатор времени выполнения (RID) и какую платформу вы используете n заранее.
Учитывая, что в моем коде отсутствует сборка времени выполнения.NET Core, я попытался загрузить сборки из папки времени выполнения.NET Core, но пока мне это не удалось.