2011-11-08 34 views
1

我有動態加載的程序集並將其轉換爲接口的問題。我的錯誤在哪裏?從動態加載程序集創建對象並將其轉換爲接口(.NET 2.0)

主應用程序(負載插件):

namespace Console_IFce_Test 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Console.WriteLine("Press any key to find IPlugin library..."); 
      Console.ReadKey();    

      string[] files = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.dll"); 
      Console.WriteLine("Loading assembly: {0}", Path.GetFileName(files[0])); 

      Assembly asm = Assembly.LoadFrom(files[0]); 
      //Trying this, but still have problems 
      //Assembly asm = Assembly.Load(File.ReadAllBytes(files[0])); 

      foreach (Type t in asm.GetTypes()) 
      { 
       Console.WriteLine("Searching in type {0}... ", t.FullName); 

       foreach (Type iface in t.GetInterfaces()) 
       { 
        Console.WriteLine("Interface found: {0}", iface.FullName); 
       } 

       if (t is IPlugin) 
       { 
        Console.WriteLine("1 - IPlugin found!"); 
        IPlugin plugin = (IPlugin)Activator.CreateInstance(t); 
        return; 
       } 

       if (typeof(IPlugin).IsAssignableFrom(t)) 
       { 
        Console.WriteLine("2 - IPlugin found!"); 
        IPlugin plugin = (IPlugin)Activator.CreateInstance(t); 
        return; 
       } 
      } 

      Console.WriteLine("All operations done! Press any key to exit..."); 
      Console.ReadKey(); 
     } 
    } 
} 

接口:

namespace Console_IFce_Test 
{ 
    interface IPlugin 
    { 
     int GetZero(); 
    } 
} 

而且插件:

namespace Library 
{ 
    public class Plugin : Console_IFce_Test.IPlugin 
    { 
     public int GetZero() 
     { 
      return 0; 
     } 
    } 
} 

在以.exe目錄 - 只有1的.dll(插件) 。因此,它的輸出:

Press any key to find IPlugin library... 
Loading assembly: Library.dll 
Searching in type Console_IFce_Test.IPlugin... 
Searching in type Library.Plugin... 
Interface found: Console_IFce_Test.IPlugin 
All operations done! Press any key to exit... 

你看,該程序發現IPlugin接口組件,但是當我試圖把它與接口比較(二條件語句) - 他們返回false。如果我試圖手動投它 - 它會返回異常「不能投」。

我發現類似的問題:Two Types not equal that should be和答案寫作者:

由不同的應用程序域[.NET]或類加載的同一類/類型 裝載機【JAVA]不會比相等,並且不可直接分配給 彼此。

但我不明白我該怎麼辦?如何?

+0

最好的辦法是創建* *只是在接口類型第3集。由主機和插件引用。這可以確保您在多個裝配中不會有相同的類型。 –

+0

我試試。沒有結果。我感覺,我犯了非常愚蠢的錯誤,但我無法理解 - 在哪裏? – DeniDoman

回答

2

您需要以某種方式讓.NET將程序集加載到相同的上下文中,以便能夠在這些程序集中的類型之間進行轉換。

1-將程序集放入應用程序路徑或GAC中,以便Load(而不是LoadFrom)函數可以找到它。

2-創建應用程序域並完成所有工作。您可以完全控制程序集搜索應用程序域的位置。

3-使用加載項模型。

閱讀這篇文章,詳細瞭解您的選擇:爲了避免這個陷阱Best Practices for Assembly Loading

2

在.NET類型的上下文以及由名區分...

而且LoadFrom負載類型在不同的環境比任何類型的正常加載到你的程序

所以,你有兩種不同類型的IPlugin,一個在默認上下文中加載,另一個在LoadFrom上下文中加載。他們不會比較相同,你不能在他們之間施放。

如果您希望它們與默認上下文中加載的類型相同,您必須確保使用LoadFrom加載的程序集引用的類型無法在LoadFrom上下文中解析。

+0

謝謝。但你有什麼想法,我怎麼能解決這個問題?我試圖使用Assembly.Load(byte [])方法,將.dll讀取到內存中,但它不工作。 – DeniDoman

相關問題