2016-12-01 129 views
3

使用VS2017 RC,.NET Core在.NET Core中加載程序集

我試圖從文件加載程序集。 該程序集的依賴關係位於同一個文件夾中。我正在使用AssemblyLoadContext.Default.LoadFromAssemblyPath

我意識到LoadFromAssemblyPath專門加載請求的程序集,忽略它的依賴關係;任何試圖遍歷裝配類型的嘗試都會失敗,並顯示System.Reflection.ReflectionTypeLoadException

LoaderExceptions包含一列System.IO.FileNotFoundException

我很好奇這是爲什麼,因爲所有需要的文件都在同一個文件夾中。

我也嘗試加載一個文件夾中的所有* .dll文件,但一些令人驚訝的失敗與System.IO.FileLoadException

我在做什麼錯?

編輯:我不想依賴.deps文件(從而排除了DependencyContext)。可能嗎?

+0

我不習慣這種有點操作,但你有沒有試過調用['Assembly.LoadFrom()'](https://msdn.microsoft.com/it-it/library/1009fa28(v = vs。 110)的.aspx)? – Phate01

+1

@ Phate01在.NET Core中沒有'Assembly.LoadFrom'。 – Raine

+0

我想你應該從GAC加載程序集,只需指定要加載的程序集的名稱(完整或短)即可。但這只是一個猜測。 –

回答

6

那麼對我而言,最合適的就是在Resolve事件中註冊一個句柄,並在LoadFromAssemblyPath需要依賴關係時按需加載所需的程序集。請注意,這是我的試驗和錯誤數小時的解決方案,所以它可能不是最理想的方法。但現在它適用於我。這裏是我的代碼:從那裏

AssemblyLoadContext.Default.Resolving += (context, name) => 
    { 
     // avoid loading *.resources dlls, because of: https://github.com/dotnet/coreclr/issues/8416 
     if (name.Name.EndsWith("resources")) 
     { 
      return null; 
     } 

     var dependencies = DependencyContext.Default.RuntimeLibraries; 
     foreach (var library in dependencies) 
     { 
      if (IsCandidateLibrary(library, name)) 
      { 
       return context.LoadFromAssemblyName(new AssemblyName(library.Name)); 
      } 
     } 

     var foundDlls = Directory.GetFileSystemEntries(new FileInfo(<YOUR_PATH_HERE>).FullName, name.Name + ".dll", SearchOption.AllDirectories); 
     if (foundDlls.Any()) 
     { 
      return context.LoadFromAssemblyPath(foundDlls[0]); 
     } 

     return context.LoadFromAssemblyName(name); 
    }; 
} 
private static bool IsCandidateLibrary(RuntimeLibrary library, AssemblyName assemblyName) 
{ 
    return (library.Name == (assemblyName.Name)) 
      || (library.Dependencies.Any(d => d.Name.StartsWith(assemblyName.Name))); 
} 

的IsCandidateLibrary()位來源: http://www.michael-whelan.net/replacing-appdomain-in-dotnet-core/

我認爲你可以忽略這一點,整個DependencyContext的一部分,但它作爲一個緩存,避免重裝相同組件一遍又一遍地。所以我保留了它。