2012-08-08 67 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之前運行在該點以下後得到nullp:上裝載

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

此代碼是第一次嘗試插件,我沒有找到爲什麼pnull呢。 我希望有人能帶領我走向正確的道路:)

+1

這段代碼不工作,x是什麼,你在哪裏啓動它? – devundef 2012-08-08 15:51:50

+0

在上面的代碼片段中,「if(x!= null)」中的「x」實際上應該是「myI」? – 2012-08-08 15:52:17

+0

您還應該驗證該類型是否具有默認構造函數,因爲您的代碼假定了這一點。 – 2012-08-08 15:52:38

回答

4

你應該喬恩斯基特這也解釋了,你看到的行爲,以及如何做插件框架適當真正讀懂Plug-ins and cast exceptions

+0

我可以從中得到的是插件的程序集與我的應用程序的程序集不一樣。 – Phil 2012-08-08 16:47:16

+0

我希望有更多的人投票贊成,因爲我認爲這可能是OP的問題。基本上,如果你認爲這個像C++,接口定義像.h文件,你會遇到這個錯誤。如果你以「託管類型」的方式思考它,你會發現有兩個接口,每個文件一個接口,如果它被編譯爲鏈接所說的(錯誤的)方式。 – 2012-08-08 16:49:20

5

有更簡單的方法來檢查您的類型是否可以轉換到您的界面。

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

如果IsAssignableFrom是假的,有什麼問題你繼承,這是你的錯誤,最有可能的原因。

+0

是的,它是'假'。但是我現在只有一個成員,並且不知道繼承可能會出現什麼問題。 – Phil 2012-08-08 16:40:11

+0

您的「插件」程序集是否引用界面定義的程序集?你的運行代碼(示例中的代碼)是否引用*相同的*程序集? – 2012-08-08 16:50:50

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

}