2010-10-07 66 views
1

我一直在試圖製作一個模塊,類似於命令行的應用程序。每個模塊可以容納多個命令。例如,「模塊A」可以具有諸如「退出」和「回聲」之類的命令。我用下面的代碼加載和初始化模塊,我...接口的實現無效

foreach (string Filename in Directory.GetFiles(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Modules"), "*.dll")) 
{ 
    Assembly Asm = Assembly.LoadFrom(Filename); 
    foreach (Type AsmType in Asm.GetTypes()) 
    { 
     if (AsmType.GetInterface("ICommandModule") != null) 
     { 
      object CommandObject = Activator.CreateInstance(AsmType); 
      ICommandModule CommandModule; 
      if (CommandObject is ICommandModule) 
      { 
       CommandModule = (ICommandModule)CommandObject; 
      } 
      else 
      { 
       throw new Exception("CommandObject is not a valid ICommandModule."); 
      } 
      ... 

我知道一個事實,即它加載的模塊(Core.dll)是完全符合於ICommandModule接口。當我確認if (CommandObject is ICommandModule)時,它會拋出異常。當我將if語句全部刪除時,它告訴我無法將CommandObject轉換爲ICommandModule

+0

您的ICommandModule接口是否在不同的名稱空間中聲明? – Grozz 2010-10-07 21:50:29

+0

如果你做了ICommandModule會發生什麼CommandObject =(ICommandModule)Activator.CreateInstance(AsmType); – 2010-10-07 21:52:49

+0

是的,Grozz。我的接口都在MyApp.Interfaces中,而我的模塊位於MyApp.Modules名稱空間中。 – 2010-10-07 21:53:04

回答

1

您的應用程序可以找到與ICommandModule裝配在兩個不同的目錄。程序集可能完全相同,但由於它們位於不同的目錄中,因此類型系統將它們視爲不同。

+0

這是我的具體應用程序的答案,但下面的是我的問題非常有效的解決方案。我正在重建模塊接口以避免此問題。謝謝! – 2010-10-08 21:46:04

0

嘗試:

CommandModule = CommandObject as ICommandModule; 
1

採取的Jakub的建議,使這一變化:

ICommandModule CommandModule = Activator.CreateInstance(AsmType) as ICommandModule; 

你可能遇到了在那裏Activator.CreateInstance(AsmType)將返回空的情況。如果是這樣,它可能是它發現了接口本身的聲明,並且沒有爲該特定的AsmType創建實例。所以,在調試時,確保你確切知道你想要實例化的類型。

1

您可以使用Reflection來檢查對象是否實現了特定的接口。

下面是一個例子:

bool isCommandModule = typeof(ICommandModule).IsAssignableFrom(commandObject); 

相關資源: