2011-04-22 55 views
7

我正在用WPF和C#構建應用程序,基本上我想允許任何人創建一個dll並將其放入一個文件夾(類似於插件)。應用程序將獲取文件夾中的所有dll,加載它們並使用它們的方法(在界面上定義)。如何在運行時引用DLL?

如何在運行時引用dll的任何想法?有什麼更好的想法如何實現這一點?

回答

9

我實現了像你所要求的,通過DLL文件在指定目錄搜索,發現班實現特定的接口。下面是我用來做這個類:

public class PlugInFactory<T> 
{ 
    public T CreatePlugin(string path) 
    { 
     foreach (string file in Directory.GetFiles(path, "*.dll")) 
     { 
      foreach (Type assemblyType in Assembly.LoadFrom(file).GetTypes()) 
      { 
       Type interfaceType = assemblyType.GetInterface(typeof(T).FullName); 

       if (interfaceType != null) 
       { 
        return (T)Activator.CreateInstance(assemblyType); 
       } 
      } 
     } 

     return default(T); 
    } 
} 

所有你需要做的就是用這樣的初始化這個類:


PlugInFactory<InterfaceToSearchFor> loader = new PlugInFactory<InterfaceToSearchFor>(); 
    InterfaceToSearchFor instanceOfInterface = loader.CreatePlugin(AppDomain.CurrentDomain.BaseDirectory); 

如果這個答案或任何其他的答案幫助你解決你的問題,請點擊複選標記將其標記爲答案。此外,如果您覺得這是一個很好的解決方案,請立即投票表示讚賞。只是以爲我會提到它,因爲它看起來並不像你接受任何其他問題的答案。

+0

是的,我也想從頭開始這樣做,您如何告訴主項目該插件具有接口方法?我的意思是,如果你想使用像objPlugIn.amethod()這樣的東西,你如何告訴主項目,以便編譯它? – 2011-04-22 03:19:29

+0

該插件需要公開一個接口,以便您知道對它的期望。該接口需要在插件和主項目之間共享,以便兩者都知道接口要求。 – 2011-04-22 03:21:58

+0

我想我的意思是如何分享插件和主應用程序之間的接口。我新接口,所以它需要我一段時間... – 2011-04-22 05:43:10

1

看看MEF。它應該提供你正在尋找的東西。

使用reflection也是一種選擇,但如果你問我,MEF將是更好的選擇。

+0

是啊,我也讀到了MEF,我可以提供我在尋找什麼的。不過,我想學習這種架構如何工作的,我想實現它... = D – 2011-04-22 03:07:16

1

我認爲你可以像

Assembly assembly = Assembly.LoadFrom("Something.dll"); 
Type type = assembly.GetType("SomeType"); 
object instanceOfSomeType = Activator.CreateInstance(type); 

啓動,那麼你可以用它

+0

我會嘗試!! !!任何想法如何我可以接口與主應用程序的DLL?我知道我必須有一個接口,但主應用程序如何知道對象instanceOfSomeType = Activator.CreateInstance(type);有這些方法嗎? – 2011-04-22 03:08:47

+0

@Homero在Cole的答案中,您可以使用** GetInterface **方法作爲您的案例 – V4Vendetta 2011-04-22 03:21:06

0
string relative = "ClassLibrary1.dll"; 
      string absolute = Path.GetFullPath(relative); 

      Assembly assembly = Assembly.LoadFile(absolute); 
      System.Type assemblytype = assembly.GetType("ClassLibrary1.Class1"); 
      object []argtoppass={1,2}; 
      var a =Activator.CreateInstance(assemblytype, argtoppass); 
      System.Type type = a.GetType(); 
      if (type != null) 
      { 
       string methodName = "add"; 
       MethodInfo methodInfo = type.GetMethod(methodName); 
       object result = methodInfo.Invoke(a, null); 

       int a1 = (int)result; 
      } 
+0

這個解決方案,它工作的很好@ Homero Barbosa – 2013-05-27 08:54:43

0

我的工作類似的東西,其中一個客戶可能有不同的版本安裝第三方DLL的,雖然名稱和位置是相同的。如果我們沒有引用正確的版本,我們會失敗。我使用反射來識別版本,但我需要修改安裝程序以根據版本使用不同的DAL類,或者通過接口使DAL版本獨立。

我傾向於第二個。如果您在代碼中創建了一個「虛擬DLL」,它實現了一個接口,該接口具有您想要從目標程序集調用的所有方法,並且不會將實際類型作爲參數傳入,而是傳入接口,那麼您應該可以使用全部你的設計時代碼中的方法和基於你的模型實現進行編譯,甚至做你的測試,但是當你在運行時加載實際的程序集時,從真正的程序集中獲取結果。 讓我知道這是否適用於你,我會讓你知道爲好。

喬伊摩根