어셈블리를 사용하여 어셈블리의 로딩을 혼합 할 때 이상한 동작.

StackOverflow https://stackoverflow.com/questions/416468

  •  03-07-2019
  •  | 
  •  

문제

어셈블리를 사용하여 어셈블리의 로딩을 혼합 할 때 이상한 동작.

Assembly.Load와 함께 어셈블리를로드 할 때 이상한 동작을 만났습니다.
어셈블리가 실행 폴더가 아닌 폴더에있는 Assembly.LoadFrom을 사용하여 어셈블리를로드하고 있습니다.

나중에 어셈블리가 이미로드된다는 사실에도 불구하고 System.io.filenotfoundException (“파일 또는 어셈블리를로드 할 수 없음…”)을 사용 하여이 어셈블리를 다시로드하려고 할 때 테스트 코드에서 나중에로드를 시도합니다. . 부하는 강한 이름과 강력한 이름으로 실패합니다 (이 어셈블리가 다시 한 번로드하는 원래 이유는 Binaryformatter의 사용입니다).

그러나 어셈블리가 실행 폴더에있는 경우 나중에로드는 두 경우 모두에 성공하며 강력한 이름과 비 강력한 이름으로 성공합니다. 이 경우 두 개의 동일한 어셈블리가 두 개의 다른 위치에서로드되어 있음을 알 수 있습니다.

이 문제를 재현하는 간단한 코드 샘플 -

어셈블리 어셈블리 1 = Assembly.Loadfrom (@"C : A.Dll");

// 강한 이름으로로드하는 조립 실패 어셈블리 2 = Assembly.Load ( "a, 버전 = 1.0.0.0, Culture = Neutral, PublicKeyToken = 14986c3f172d1c2c");

// 비 강력한 실패 실패 어셈블리 조립 3 = Assembly.Load (@"a");

  1. CLR이 이미로드 된 어셈블리를 무시하는 이유는 무엇입니까?
  2. 이 문제를 어떻게 완화 할 수 있습니까?

감사.

도움이 되었습니까?

해결책

이상하지 않습니다. 문서에 따라로드 및로드로로드하면 어셈블리가 다른 상황에 놓입니다. 이것 도움이 될 수 있습니다.

  1. CLR이 이미로드 된 어셈블리를 무시하는 이유는 무엇입니까?

그들은 다른 맥락에 있기 때문에.

  1. 이 문제를 어떻게 완화 할 수 있습니까?

동일한 컨텍스트에서로드하거나 CLR이 어셈블리를 찾도록 핸들러를 부착하여 AppDomain.AssemblyResolve.

대안

어셈블리를로드하는 위치가 AppDomain의 하위 폴더 인 경우 Basedirectory는 간단히 app.config에 항목을 추가 할 수 있습니다.

<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <probing privatePath="bin;bin2\subbin;bin3"/>
      </assemblyBinding>
   </runtime>
</configuration>

http://msdn.microsoft.com/en-us/library/823z9h8w.aspx

다른 팁

@kent boogart : 그것은 올바른 설명 인 것 같습니다. 전체 설명을 위해, Suzanne Cook 은이 블로그 게시물을 가지고있는이 블로그 게시물을 가지고 있습니다.http://blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx

다음은 AppDomain.assemblyresolve를 활용하는 코드입니다.

 // register to listen to all assembly resolving attempts:
 AppDomain currentDomain = AppDomain.CurrentDomain;
 currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);


 // Check whether the desired assembly is already loaded
 private static Assembly MyResolveEventHandler(object sender, ResolveEventArgs args) {
    Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
    foreach (Assembly assembly in assemblies) {
       AssemblyName assemblyName = assembly.GetName();
       string desiredAssmebly = args.Name;
       if (assemblyName.FullName == desiredAssmebly) {
           return assembly;
       }
    }

    // Failed to find the desired assembly
    return null;
 }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top