c#動態加載dll並調用dll中類的方法


當然,這里指的是托管的dll與托管的方法,實際上用到的東西大部分是在反射(reflecting)命名空間里頭的。
用途或許廣泛吧,我不是很確信,但這個是在運行期綁定的,那么就不會有編譯期綁定那么僵硬……但也沒有編譯期綁定那么簡單。
可以用於做插件之類的。
先是一個接口,實現了這個接口的類被認為是合法的,可以被載入的……

namespace gp
{
    public delegate void DoWhat();
    public interface IInterface
    {
        string GetName();
        DoWhat dowhat { get; set; }
    }
}

很簡單的接口,一個是用於判斷做什么的函數,另外一個,則是一個方法的委托,做什么。
然后,我們新建一個項目,弄個類實現這個接口:

 

namespace gp
{
    public delegate void DoWhat();
    public interface IInterface
    {
        string GetName();
        DoWhat dowhat { get; set; }
    }
}

在構造函數里頭將委托加了一個項,當執行那個委托的時候就會執行這個函數。
現在是重要的一個部分,代碼難度不大~~
新建一個windows application,然后在窗體上頭拖一個panel,這個是為了動態加載后將操作按鈕放上去的。。不過可能會重疊,建議考慮用flowlayoutpanel,這個會自動重排以滿足個數,anyway,無所謂,反正是為了闡述概念。

        private void Form1_Load(object sender, EventArgs e)
        {
            var plugindir = System.IO.Directory.GetParent(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName).CreateSubdirectory("startup");
            foreach (var filesInPlugin in plugindir.GetFiles())
            {
                if (filesInPlugin.Extension.ToLower() == ".dll")
                {
                    Assembly dllFromPlugin = Assembly.LoadFile(filesInPlugin.FullName);
                    foreach (var dllModule in dllFromPlugin.GetLoadedModules())
                    {
                        foreach (var typeDefinedInModule in dllModule.GetTypes())
                        {
                            if (typeDefinedInModule.GetInterfaces().Contains(typeof(gp.IInterface)))
                            {
                                if (typeDefinedInModule.IsClass)
                                {
                                    var itemGet = System.Activator.CreateInstance(typeDefinedInModule) as gp.IInterface;
                                    LinkLabel ll_now = new LinkLabel();
                                    ll_now.Text = itemGet.GetName();
                                    ll_now.Click += (a, b) => { if (itemGet.dowhat != null)itemGet.dowhat(); };
                                    panel1.Controls.Add(ll_now);
                                }
                            }
                        }
                    }
                }
            }
        }

一個不難看懂的代碼,先是指定插件文件夾的位置,要是沒有就創建一個。然后遍歷里頭為dll類型的文件,再試圖轉載這個文件——實際情況下,這里需要加 try...catch,因為誰也不知道你加載的dll文件倒是是不是合法的dll文件,然后遍歷里頭的模塊,再遍歷模塊里頭的定義的類型——可能是類、 interface、枚舉等等等等,很多很多,取得這個玩意兒的集成的interface,再判斷是不是包含我們的interface。(也就是說,包含了這個interface就算是合法的插件類)
如果包含了的話,判斷這是不是一個類,因為接口也可以在其他的東西里頭被繼承,比如另一個接口等等,而其他這些情況對我們來說毫無意義。
然后,我們動態創建這個類的實例—— System.Activator.CreateInstance,並且進行轉換,轉換為繼承的接口,現在開始就是強類型操作了。我這里做的操作是生成一個linklabel,並且設置名稱和按下執行的方法。。。大概就是這樣,以上。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM