zoukankan      html  css  js  c++  java
  • 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,并且设置名称和按下执行的方法。。。大概就是这样,以上。

  • 相关阅读:
    死磕算法第一弹——数组、集合与散列表
    拼写纠正
    IntelliJ系列IDE中的project和module
    【Spring】学习SpringAOP
    MyEclipse打开Jsp报错Failed to create the part's controls
    【Spring】学习SpringIoC
    【GitHub】Set up GitHub for Win10
    【<meta name="" content=">】的作用
    【JSP】修改网页ico小图标
    【JSP】导航栏悬停顶部简单特效
  • 原文地址:https://www.cnblogs.com/slayercat/p/2519741.html
Copyright © 2011-2022 走看看