2009-11-23 31 views
1

基本上我想能夠爲我的應用程序編寫一個dll,我將能夠使用特定名稱放入特定文件夾,並且在運行時將該dll加載並訂閱特定事件。 作爲一個例子,我有一個簡單的Windows窗體應用程序,它上面有一個按鈕。我希望能夠在發生按鈕單擊事件時顯示MessageBox,但我希望顯示的消息由運行時加載的外部dll控制。 完成此操作的最佳方法是什麼?從運行時加載的dll連接事件?

回答

3

創建包含至少一個方法來處理事件(您的應用程序必須引用在此定義的組件)的接口:

public interface IEventHandler { 
    void HandleEvent(object sender, EventArgs e); 
} 

添加類要加載的dll在運行時實現接口:

public class ConcreteEventHandler: IEventHandler { 
    public void HandleEvent(object sender, EventArgs e) { 
     // do something here 
    } 
} 

在應用程序中,使用反射來加載DLL並創建具體處理程序的實例(檢查省略錯誤):

// The assembly name/location could be configurable 
Assembly  assembly = Assembly.Load("MyAssembly.dll"); 
// The type name could be configurable 
Type   type  = assembly.GetType("ConcreteEventHandler"); 
IEventHandler handler = Activator.CreateInstance(type) as IEventHandler; 

您可以掛鉤此處理多達任何你想要的,例如:

MyButton.OnClick += handler.HandleEvent; 
+0

感謝。當我到達最後一行示例代碼時,我從MyButton.OnClick + = handler.HandleEvent更改爲MyButton.Click + = HandleEvent,我在此行上收到「對象引用未設置爲對象的實例」錯誤。我錯過了什麼? – etoisarobot 2009-11-23 18:57:17

+0

您可以忽略上述有關空引用錯誤的註釋。我將dll複製到sep dir以在運行時導入,然後繼續在Visual Studio中工作,因此我正在處理的dll不是正在處理的dll。咄。謝謝。你的例子非常有幫助。 – etoisarobot 2009-11-23 19:54:24

+0

這是通過反射加載「可插拔」組件的永恆陷阱之一 - 如果您想了解它的好方法,請告訴我們! :)我最好推薦的是添加代碼來檢查一切,並拋出非常特定的異常,如:if(!File.Exists(assemblyPath)){throw new FileNoteFoundException(string.Format(「Can not locate assembly at {0 },「assemblyPath)); }'。 (併爲類型添加類似的東西等) – 2009-11-23 20:07:59

0

該DLL是單個知名的DLL,還是將加載不同的或多個?如果是後者,我建議查看.NET 3.5中的AddIn框架。

鑑於這些選擇,在這種情況下使用的非常好的設計模式是Observer pattern。你的「觀察者」正在觀看按鈕點擊事件(觀察)並適當地執行他們的MessageBox(es)。