本代碼實現DLL的動態加載, 類似PS里的濾鏡插件!
1. 建立一個接口項目類庫,此處名稱為:Test.IPlugin
using System; namespace Test.IPlugin { public interface IPlugin { void Run(object obj); } }
2.建立一個DLL插件類庫項目,此項目要引用接口項目'Test.IPlugin',並實現Run方法, 此處名稱為:Test.Plugin
using System; namespace Test.Plugin { public class Plugin:IPlugin.IPlugin { #region IPlugin 成員 void Test.IPlugin.IPlugin.Run(object obj) { System.Windows.Forms.MessageBox.Show(obj.ToString()); } #endregion } }
3.插件動態加載實現,建立控制台或者WinForm項目及引用接口項目Test.IPlugin, 以下為動態加載代碼
private void btnLoad_Click(object sender, EventArgs e) { string filePath = @"文件路徑\Test.Plugin.dll"; Assembly dll = null; {//方法一:直接從DLL路徑加載(網上代碼,本機測試出錯) //dll = Assembly.Load(filePath); } {//方法二:先把DLL加載到內存,再從內存中加載 FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fs); byte[] bFile = br.ReadBytes((int)fs.Length); br.Close(); fs.Close(); dll = Assembly.Load(bFile); } //調用接口 foreach (var t in dll.GetTypes()) { if (t.GetInterface("IPlugin") != null) { var plugin = (IPlugin.IPlugin)Activator.CreateInstance(t); plugin.Run("test"); } } }
以上為實現動態插件模式的代碼,先注意下調用插件的代碼中有2種方法
----------------分割線---------------
注意第一種方法, 在Assembly.Load(filePath)時會拋出異常:
未能加載文件或程序集“***”或它的某一個依賴項。給定程序集名稱或基本代碼無效。 (異常來自 HRESULT:0x80131047)
在網上查了很多相關解決方案均未能解決這個錯誤,開發環境為VS2008,三個項目均為Framework2.0 X86模式,嘗試過的方式
1.強制CPU模式為X86 2.所有DLL及EXE放置同一目錄 3.取消"啟用Visual Studio宿主進程"
最后無意中看到有用加載到內存的方式,然后使用BinaryReader讀取字節數組再加載, 完美解決.