7

我正在尝试动态加载包含 ASP.NET CoreStartup类的 .NET Core DLL。然后我想实例化这个Startup类并将它交给TestHostAPI,这样我就可以在内存中启动站点。我编写了以下代码:

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=Method 'ConfigureServices' in type 'Foo.Startup' from assembly 'Foo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' 没有实现。Source= StackTrace:在 System.Reflection.RuntimeAssembly.GetExportedTypes(RuntimeAssembly 程序集,ObjectHandleOnStack retTypes)在 System.Reflection.RuntimeAssembly.GetExportedTypes()

我认为加载 ASP.NET Core 和其他第三方 DLL(如 Newtonsoft.Json)时遇到问题。

4

1 回答 1

-1

我对这个答案不满意,如果它对某人有帮助,我会发布它。

我正在做一个dotnet publish然后尝试从发布的输出中运行我的应用程序。我设法通过使用以下命令发布一个自包含的应用程序来使其工作:

dotnet publish --self-contained --framework netcoreapp1.1 --runtime win7-x64

自包含应用程序包含运行应用程序所需的所有程序集,包括 .NET Core 运行时。我想避免这样做,因为它要求您事先知道运行时标识符 (RID) 以及您正在运行的平台。

鉴于我上面的代码缺少 .NET Core 运行时程序集的知识,我尝试从 .NET Core 运行时文件夹加载程序集,但到目前为止这对我来说失败了。

于 2017-07-07T15:29:23.510 回答