2012-08-08 2 views
6

일부 .dll 파일을 동적으로로드하려고합니다. 파일은 MyInterface을 구현하는 클래스가 하나 이상있는 플러그인 (현재는 자체 작성)입니다.C# 인터페이스 목록에 클래스 캐스팅

Dictionary<MyInterface, bool> _myList; 

    // ...code 

    Assembly assembly = Assembly.LoadFrom(currentFile.FullName); 
    foreach (Type type in assembly.GetTypes()) 
    { 
     var myI = type.GetInterface("MyInterface"); 
     if(myI != null) 
     { 
      if ((myI.Name == "MyInterface") && !type.IsAbstract) 
      { 
       var p = Activator.CreateInstance(type); 
       _myList.Add((MyInterface)p, true); 
      } 
     } 
    } 

이이 캐스트 예외가 발생합니다 실행,하지만 난 해결 방법을 찾을 수 없습니다 : 각 파일에 대해 나는 다음과 같은 일을 해요. 어쨌든 이것이 왜 전혀 작동하지 않는지 궁금합니다. .NET Framework 3.5 솔루션을 찾고 있어요.

내게 일어난 또 다른 것은 위의 코드에서 _myList에 새 항목을 추가하기 전에 지점에서 다음을 실행 한 후 pnull을 얻고 있었다

다음로드의 첫 번째 시도를

var p = type.InvokeMember(null, BindingFlags.CreateInstance, null, 
          null, null) as MyInterface; 

이 코드가되었다 플러그인, 난 pnull 아직 이유를 찾지 못했습니다. 누군가 나를 올바른 방향으로 이끌 수 있기를 바랍니다 :)

+1

이 코드는 작동하지 않습니다. x는 무엇이며 어디에 초기화합니까? – devundef

+0

위의 코드 조각에서 "if (x! = null)"의 "x"는 실제로 "myI"가됩니까? –

+0

코드에서 가정하기 때문에 유형에 기본 생성자가 있는지 확인해야합니다. –

답변

4

당신은 정말 당신이보고 행동과 방법을 제대로 플러그인 프레임 워크를 수행하는 방법을 설명 존 소총으로 Plug-ins and cast exceptions을 읽어야합니다.

+0

플러그인의 어셈블리가 응용 프로그램의 어셈블리와 같지 않다는 점을 알아 냈습니다. – Phil

+0

아마 OP의 쟁점이라고 생각하는만큼 더 많은 사람들이이 투표에 참여할 수 있기를 바랍니다. 기본적으로 C++과 인터페이스 정의 (예 : .h 파일)를 생각하면이 오류가 발생합니다. "관리 유형"방식으로 생각하면 링크 당 하나씩 잘못된 방식으로 컴파일되는 경우 파일 당 하나씩 두 개의 인터페이스가 있다는 것을 알 수 있습니다. –

5

유형을 인터페이스에 캐스트 할 수 있는지 확인하는 훨씬 쉬운 방법이 있습니다. IsAssignableFrom이 거짓

Assembly assembly = Assembly.LoadFrom(currentFile.FullName); 
foreach (Type type in assembly.GetTypes()) 
{ 
    if(!typeof(MyInterface).IsAssignableFrom(type)) 
     continue; 

    var p = Activator.CreateInstance(type); 
    _myList.Add((MyInterface)p, true); 
} 

경우, 오류의 가장 큰 원인이다 당신의 상속에 문제가있다.

+0

물론 그렇습니다. 거짓입니다. 그러나 나는 현재 단 하나의 멤버 만 가지고 있으며 상속에 어떤 문제가 있는지 알지 못합니다. – Phil

+0

"플러그인"어셈블리가 인터페이스가 정의 된 어셈블리를 참조합니까? 실행중인 코드 (샘플 코드)가 * 동일한 * 어셈블리를 참조합니까? –

1

다음 코드를 살펴보십시오. 나는이 상황에서 Type.IsAssignableFrom(Type type)가 당신을 도울 수 있다고 생각한다.

Assembly assembly = Assembly.LoadFrom(currentFile.FullName); 
///Get all the types defined in selected file 
Type[] types = assembly.GetTypes(); 

///check if we have a compatible type defined in chosen file? 
Type compatibleType = types.SingleOrDefault(x => typeof(MyInterface).IsAssignableFrom(x)); 

if (compatibleType != null) 
{ 
    ///if the compatible type exists then we can proceed and create an instance of a platform 
    found = true; 
    //create an instance here 
    MyInterface obj = (ALPlatform)AreateInstance(compatibleType); 

} 
관련 문제