2016-12-01 5 views
3

VS2017 RC, .NET 코어 사용.NET에서 어셈블리로드

파일에서 어셈블리를로드하려고합니다. 이 어셈블리의 종속성은 같은 폴더에 있습니다.

나는 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

로드하려는 어셈블리의 이름 (full 또는 short)을 지정하여 GAC에서 어셈블리를로드해야한다고 생각합니다. 그러나 그것은 단지 추측입니다. –

답변

6

잘 맞는 점은 Resolving 이벤트에 핸들을 등록하고 LoadFromAssemblyPath에 종속성이 필요할 때 필요한 어셈블리를로드하는 것입니다. 시행 착오를 거친이 솔루션은 가장 이상적인 방법이 아닐 수도 있습니다. 그것은 지금까지는 나를 위해 작동합니다. 난 당신이 전체 DependencyContext 부분을 생략 할 수 있다고 생각 http://www.michael-whelan.net/replacing-appdomain-in-dotnet-core/

하지만 캐시의 역할과 같은 어셈블리를 다시로드 방지 :

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() 비트가 거기에서 유래 : 여기에 내 코드입니다 다시 반복하여. 그래서 나는 그것을 지켰다.