2012-08-08 13 views
6

Próbuję załadować niektóre pliki .dll dynamicznie. Pliki to wtyczki (na razie napisane samodzielnie), które mają co najmniej jedną klasę, która implementuje MyInterface. Dla każdego pliku wykonuję następujące czynności:C# rzucić klasę na listę interfejsów

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); 
      } 
     } 
    } 

Uruchomienie tego powoduje wyjątek odlewania, ale nie można znaleźć obejścia. W każdym razie zastanawiam się, dlaczego to w ogóle nie działa. Szukam rozwiązania w .NET Framework 3.5.

Inną rzeczą, która się do mnie trafiało null w p po uruchomieniu następujące w punkcie przed dodaniem nowego wpisu do _myList w powyższym kodzie:

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

Ten kod został pierwszą próbę na ładowanie wtyczek, nie dowiedziałem się jeszcze, dlaczego p był już null. Mam nadzieję, że ktoś może mnie poprowadzić we właściwy sposób :)

+1

ten kod nie działa, co to jest X i gdzie go zainicjować? – devundef

+0

W powyższym fragmencie kodu jest "x" w "if (x! = Null)" naprawdę powinno być "myI"? –

+0

Powinieneś również sprawdzić, czy typ ma domyślny konstruktor, ponieważ twój kod to zakłada. –

Odpowiedz

4

Należy naprawdę czytać Plug-ins and cast exceptions Jon Skeet, który wyjaśnia zachowanie widzisz i jak to zrobić ram wtykowych prawidłowo.

+0

Mogłem z tego wyciągnąć to, że zestaw wtyczki nie jest taki sam jak zestaw mojej aplikacji. – Phil

+0

Chciałabym, żeby więcej osób zagłosowało na ten temat, ponieważ uważam, że to prawdopodobnie kwestia PO. Zasadniczo, jeśli myślisz o tym jak C++ i definicji interfejsu jak plik .h, napotkasz ten błąd. Jeśli myślisz o tym w "zarządzanych typach", zobaczysz, że istnieją dwa interfejsy, po jednym na plik, jeśli jest on kompilowany (niewłaściwy) sposób, w jaki mówi link. –

5

Istnieje znacznie prostszy sposób sprawdzenia, czy Twój typ można przesłać do interfejsu.

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); 
} 

Jeśli IsAssignableFrom jest fałszywa, jest coś nie tak z dziedziczenia, który jest najbardziej prawdopodobną przyczyną twoich błędów.

+0

dobrze, tak, to "false". Jednak mam teraz tylko jednego członka i naprawdę nie wiem, co może być nie tak ze spadkiem. – Phil

+0

Czy twój zestaw "wtyczki" odwołuje się do zestawu, w którym definiowany jest interfejs? Czy twój działający kod (kod w próbce) odwołuje się do tego samego * zestawu? –

1

Proszę spojrzeć na poniższy kod. Myślę, że Type.IsAssignableFrom(Type type) może ci pomóc w tej sytuacji.

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); 

} 
Powiązane problemy