Динамическая загрузка базовой сборки 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, но пока мне это не удалось.

Другие вопросы по тегам