.net 如何在当前应用程序域中加载另一个程序集?

.net 如何在当前应用程序域中加载另一个程序集?,.net,asp.net-core,appdomain,.net,Asp.net Core,Appdomain,该问题取自github问题,具体涉及使用另一个程序集的启动来构建WebHost 在通过WebHostBuilderExtensions.UseStartup配置的IWebHostBuilder上调用.Build(),其中startupType通过其字符串程序集名称从单独的.exe程序集检索时,依赖项注入失败 对于默认的ASP.NET Core+.NET Framework项目,将抛出以下内容: System.invalidoOperationException:“在尝试激活“WebAppWith

该问题取自github问题,具体涉及使用另一个程序集的
启动来构建
WebHost

在通过
WebHostBuilderExtensions.UseStartup配置的
IWebHostBuilder上调用
.Build()
,其中
startupType
通过其字符串程序集名称从单独的
.exe
程序集检索时,依赖项注入失败

对于默认的ASP.NET Core+.NET Framework项目,将抛出以下内容:
System.invalidoOperationException:“在尝试激活“WebAppWithAfterBuildTarget.Startup”时,无法解析类型为“Microsoft.Extensions.Configuration.IConfiguration”的服务。”

最小复制步骤

以net462为目标创建名为“MsBuildTask”的简单库项目

添加对
Microsoft.Build.[Framework/Utilities.v4.0]
程序集的引用,以及对
Microsoft.AspNetCore
+
.Http.Abstractions
nugets的引用

创建这样一个类:

public class RunStartup : Microsoft.Build.Utilities.Task
{
    public string AssemblyToLoad { get; set; }

    public override bool Execute()
    {
        var startupAssembly = Assembly.LoadFrom(Path.Combine(Directory.GetCurrentDirectory(), AssemblyToLoad));
        var builder = WebHost.CreateDefaultBuilder();
        builder.UseStartup(startupAssembly.FullName);
        var host = builder.Build();

        // ... do more stuff
        return true;
    }
}
生成MsBuildTask项目,将路径复制到dll输出(下面使用)

在visual studio中创建ASP.NET Core 2.0+.NET Framework 462项目

在webapp csproj文件中,添加

<UsingTask AssemblyFile="..\MsBuildTask\bin\Debug\net462\MsBuildTask.dll" TaskName="RunStartup" />
<Target Name="RunStartup" AfterTargets="AfterBuild">
  <RunStartup AssemblyToLoad="$(OutputPath)$(AssemblyName).exe" />
</Target>
使用这样定义的OnResolve,实际上是强制从asp.net核心项目的bin目录加载DLL

    private Assembly OnResolve(object sender, ResolveEventArgs args)
    {
        String currentFolder = Path.Combine(Directory.GetCurrentDirectory(), AssemblyToLoad);
        AssemblyName requestedName = new AssemblyName(args.Name);
        var resolvedAssembly = Assembly.LoadFrom(Path.Combine(currentFolder, requestedName.Name + (requestedName.Name == this.AssemblyName ? ".exe" : ".dll")));
        if (resolvedAssembly.GetName().Version < requestedName.Version)

        {
            return null;
        }

        return resolvedAssembly;
    }
私有程序集OnResolve(对象发送方、ResolveEventArgs args args)
{
字符串currentFolder=Path.Combine(Directory.GetCurrentDirectory(),AssemblyToLoad);
AssemblyName requestedName=新的AssemblyName(args.Name);
var resolvedAssembly=Assembly.LoadFrom(Path.Combine(currentFolder,requestedName.Name+(requestedName.Name==this.AssemblyName?”.exe“:.dll”));
if(resolvedAssembly.GetName().Version
然而,由于某些原因,这似乎失败了,出现了以下例外情况:

System.Reflection.TargetInvocationException
  HResult=0x80131604
  Message=Exception has been thrown by the target of an invocation.
  Source=mscorlib
  StackTrace:
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
   at Swashbuckle.AspNetCore.MSBuild.SwaggerGenerator.Execute() in C:\dev\Swashbuckle.AspNetCore\src\Swashbuckle.AspNetCore.MSBuild\SwaggerGenerator.cs:line 42
   at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()
   at Microsoft.Build.BackEnd.TaskBuilder.<ExecuteInstantiatedTask>d__26.MoveNext()

Inner Exception 1:
MissingMethodException: Method not found: 'Newtonsoft.Json.JsonSerializerSettings Microsoft.AspNetCore.Mvc.MvcJsonOptions.get_SerializerSettings()'.
System.Reflection.targetingException
HResult=0x8013164
Message=调用目标已引发异常。
Source=mscorlib
堆栈跟踪:
位于System.RuntimeMethodHandle.InvokeMethod(对象目标、对象[]参数、签名符号、布尔构造函数)
位于System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(对象obj,对象[]参数,对象[]参数)
在System.Reflection.RuntimeMethodInfo.Invoke(对象obj、BindingFlags invokeAttr、绑定器绑定器、对象[]参数、CultureInfo区域性)
在System.Reflection.MethodBase.Invoke(对象obj,对象[]参数)处
在C:\dev\swashback.AspNetCore\src\swashback.AspNetCore.MSBuild\SwaggerGenerator.Execute()中的swashback.AspNetCore.MSBuild.SwaggerGenerator.Execute()处:第42行
位于Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ItaskeExecutionHost.Execute()
在Microsoft.Build.BackEnd.TaskBuilder.d_uu26.MoveNext()中
内部异常1:
MissingMethodException:找不到方法:“Newtonsoft.Json.Json序列化设置Microsoft.AspNetCore.Mvc.MvcJsonOptions.get_SerializerSettings()”。

davidfowl的评论指出这是一个appdomain/context问题:对于其他上下文,PRU将其设置为将Swashback Cli工具移植到.NET Framework中
System.Reflection.TargetInvocationException
  HResult=0x80131604
  Message=Exception has been thrown by the target of an invocation.
  Source=mscorlib
  StackTrace:
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
   at Swashbuckle.AspNetCore.MSBuild.SwaggerGenerator.Execute() in C:\dev\Swashbuckle.AspNetCore\src\Swashbuckle.AspNetCore.MSBuild\SwaggerGenerator.cs:line 42
   at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()
   at Microsoft.Build.BackEnd.TaskBuilder.<ExecuteInstantiatedTask>d__26.MoveNext()

Inner Exception 1:
MissingMethodException: Method not found: 'Newtonsoft.Json.JsonSerializerSettings Microsoft.AspNetCore.Mvc.MvcJsonOptions.get_SerializerSettings()'.