2010-04-28 2 views
11

다음은 설정입니다.어셈블리를 퍼지 방법으로 해결

순수 DotNET 클래스 라이브러리는 관리되지 않는 데스크톱 응용 프로그램에 의해로드됩니다. 클래스 라이브러리는 플러그인의 역할을합니다. 이 플러그인로드 작은 아기 자신의 플러그인 (모든 DOTNET 클래스 라이브러리), 그리고 그 작은 아기 플러그인 참조를 할 때 문제가 발생 한 후, 바이트 스트림으로 메모리에

Assembly asm = Assembly.Load(COFF_Image); 

을 DLL을 읽어 그렇게 다른 dll에. 디스크에서 직접로드되지 않고 메모리를 통해로드되기 때문에 프레임 워크는 종종 이러한 참조 된 어셈블리를 찾을 수 없으므로로드 할 수 없습니다.

내 프로젝트에 AssemblyResolver 처리기를 추가 할 수 있으며 이러한 참조 된 어셈블리가 이전에 삭제 된 것을 볼 수 있습니다. 이 참조 된 어셈블리를 디스크에서 찾을 수있는 위치에 대해 상당히 좋은 생각이 있지만 Assmely로드하는 것이 올바른지 확인하려면 어떻게해야합니까?

요약하면 System.ResolveEventArgs.Name 필드에서이 DLL이 숨길 수있는 모든 폴더 목록이 있다고 가정하면 dll 파일 경로로 어떻게 안정적으로 이동합니까?

답변

6

이전에이 파일을 사용했을 때 이름이있는 ResolveEventArgs.Name 부분과 파일 이름을 비교했습니다. 정확히 동일한 버전을로드하고 있는지 확인하려면 이름이 일치하는지 확인하고 어셈블리를로드 한 다음 ResolveEventArgs.Name에 대해 어셈블리 전체 이름을 확인하면됩니다. 이 라인을 따라

뭔가 : 완전성에 대해

string name = GetAssemblyName (args); //gets just the name part of the assembly name 
foreach (string searchDirectory in m_searchDirectories) 
    { 
    string assemblyPath = Path.Combine (executingAssemblyPath, searchDirectory); 
    assemblyPath = Path.Combine (assemblyPath, name + ".dll");   
    if (File.Exists (assemblyPath)) 
     {    
     Assembly assembly = Assembly.LoadFrom (assemblyPath); 
     if (assembly.FullName == args.Name) 
      return assembly; 
     } 
    } 

는 :

private string GetAssemblyName (ResolveEventArgs args) 
    { 
    String name; 
    if (args.Name.IndexOf (",") > -1) 
     { 
     name = args.Name.Substring (0, args.Name.IndexOf (",")); 
     } 
    else 
     { 
     name = args.Name; 
     } 
    return name; 
    } 
+0

샘, 이건 좀 낭비가 아닐까요? 올바른 조립품을 찾을 때까지 조립할 필요가 없나요? –

+2

우리가 해결하려고하는 어셈블리와 같은 이름을 가진 dll 만로드합니다. 내가했을 때 그것은 내가 필요한 1 dll을로드하는 것을 의미하지만 dll과 어셈블리가 동일한 이름을 가지지 않으면 모든 dll을로드하고 찾고있는 이름과 어셈블리 이름을 비교해야합니다. –

+0

그리고 내 AppDomain을 오염시키는 것을 막을 수있는 유일한 방법은 다른 AppDomain을 만들고 먼저로드하는 것입니다. –

1

나는 AssemblyResolver에 결코 운이 없었습니다. 일반적으로 다음 세 가지 중 하나를 수행합니다.

  1. GAC에없는 외부 참조가 필요하지 않습니다. 그들이 망할 경우 ILMerge에게 알리십시오.
  2. 플러그인을 사용하여 모든 dll을 알려진 플러그인 디렉토리에 덤프해야합니다. 해당 디렉토리의 모든 어셈블리를 메모리에로드합니다.
  3. 융합에 의해 검색되는 경로에 플러그인 종속성이 필요합니다. 바인더가 어셈블리를 찾고 퓨전 로그를 찾을 위치를 파악할 수 있습니다 (fuslogvw.exe - 로깅을 켜면 재부팅하는 것을 잊지 마십시오!).
2

Managed Extensibility Framework (MEF) 모든 문제를 해결할 수 있습니다 뭔가처럼 들린다. 폴더를 검색하여 DLL을 찾고, 깊이에 대한 종속성을 해결하고, 일반적으로 플러그인 구성을 관리 할 수 ​​있습니다. 각 부분 (또는 '플러그인')은 필요한 부분과 제공하는 부분을 선언해야하며 MEF는 배선을 처리합니다. MEF가 VS2010의 확장 성 짐사의 길들이기에 성공하면 아무 것도 처리 할 수 ​​없습니다.