2013-08-06 2 views
1

자주 변경되는 소프트웨어 용 플러그인을 만들었습니다. 내 플러그인이 주 소프트웨어의 모든 새 버전에서 작동하도록합니다. 그래서 리플렉션을 통해 플러그인의 주요 오브젝트를 만들기 전에 내 플러그인에 대한 종속성 (기본 소프트웨어의 실행 파일)을로드하는 것입니다.C# reflection : DLL이 완전히로드 될 때까지 기다린 다음 개체를 만드시겠습니까?

그러나 이것이 항상 작동하지는 않습니다. 타이밍 문제가 있습니다. DLL은 (완전히)로드되지 않지만 주 오브젝트를 작성하는 코드가 실행됩니다. 의존성이 없다는 예외가 발생합니다.

개체를 만들기 전에 DLL이 완전히로드 될 때까지 기다리는 방법은 무엇입니까?

class PluginStarter 
    { 
     private MainPluginObject mainPluginObject = null; 

     public PluginStarter() 
     { 
      AppDomain.CurrentDomain.AssemblyResolve += (sender, eventArgs) => 
      { 
       var fullAssemblyName = new AssemblyName(eventArgs.Name);    

       if (fullAssemblyName.Name.Equals("MainSoftware")) 
       { 
        var found = Assembly.LoadFile(Path.Combine(Environment.CurrentDirectory, AppDomain.CurrentDomain.FriendlyName)); 
        return found; 
       } 
       else 
       { 
        return null; 
       } 
      }; 

      Initialize(); 
     } 

     private void Initialize() 
     { 
      mainPluginObject = new MainPluginObject(); 
     } 

     public void ShowForm() 
     { 
      mainPluginObject.ShowForm(); 
     } 

     public void Dispose() 
     { 
      mainPluginObject.Dispose(); 
     } 
    } 

는 최대한 빨리 [MethodImpl(MethodImplOptions.NoInlining)]으로 Initialize() 방법에 대한에 라이닝 비활성화로 그냥 작동합니다. 올바른 해결책을 여기에서 제거하고 있습니까? Assembly에 DLL로드 상태를 알리는 이벤트가 없다면 어떻게해야합니까? 하여 메소드에 늘어선 경우

+0

'null'을 반환하는 어셈블리를 확인 했습니까? –

+0

@ LasseV.Karlsen : 다른 모든 것에 대해 'null'을 반환하고 싶습니다. –

+0

'Assembly.LoadFile' 대신'Assembly.LoadFrom'을 시도해보고 차이가 있는지 확인하십시오. [this]에 대한 자세한 내용 (http://stackoverflow.com/questions/1477843/difference-between-loadfile-and-loadfrom-with-net-assemblies). – Noseratio

답변

1

은 다음 DLL이 요구 될 것이고 따라서 (메소드가 컴파일 될 때)하여 PluginStarter 생성자라고하고 AssemblyResolve 이벤트가 초기화되기 전에, 특히 뜻 전에 로드.

그래서 Initialize가 안쪽에 있는지 확인하거나 AssemblyResolve 코드를 정적 생성자에 넣어야합니다.

정적 생성자를 사용하면 생성되는 PluginStarter 객체의 수에 관계없이 하나의 이벤트 만 생성되기 때문에 아마 더 깨끗합니다.

관련 문제