C# 动态加载dll(.net)示例

dll函数库源码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace cl1
{
    public class Class1
    {
        private  string Name;
        private int Age;
        public Class1() { Name = "name"; Age = 0; }
        public Class1(string name) { Name = name; Age = 0; }
        public Class1(string name,int age) { Name = name; Age = age; }
        public static void M1()
        {
            MessageBox.Show("静态无参函数");
        }
        public static void M2(string name)
        {
            MessageBox.Show($"静态带参函数String{name}");
        }
        public static void M2(string name, int age)
        {
            MessageBox.Show($"静态带参函数int{name+age}");
        }
        public void M3()
        {
            MessageBox.Show($"非静态无参函数name={Name},age={Age}");
        }
        public void M4(string name)
        {
            MessageBox.Show($"非静态带参函数string{name}");
        }
        public void M4(int age)
        {
            MessageBox.Show($"非静态带参函数int{age}");
        }
        public void M5(string name) { MessageBox.Show(name); }
    }
}
View Code

调用尝试

public static void test()
        {
            Assembly assembly;
            Type type;

            string path = @"G:\Base\SelfBasic\cl1\bin\Debug\cl1.dll";
            assembly = Assembly.LoadFrom(path);
            //获取程序集实例中具有指定名称的Type对象
            type = assembly.GetType("cl1.Class1");
            //获取Class1对象
            var C1 = Activator.CreateInstance(type);//构造函数public Class1() 
            var C2 = Activator.CreateInstance(type, "string");//构造函数public Class1(string name) 
            var C3 = Activator.CreateInstance(type, "string", 123);//构造函数public Class1(string name,int age) 
            //获取方法
            var m1 = type.GetMethod("M1");//方法名M1在Class1类中没有重载,获取明确 方法为私有或不存在时返回null
            var val1 = m1.Invoke(null, null);//运行m1 M1函数为静态的,且无参,Invoke中参数可为null

            var m2 = type.GetMethod("M2", new Type[] { typeof(string) });//获取public static void M2(string name)
            var val2 = m2.Invoke(null, new object[] { "str" });//运行m2

            var m3 = type.GetMethod("M2", new Type[] { typeof(string), typeof(int) });//获取public static void M2(string name, int age)
            var val3 = m3.Invoke(null, new object[] { "str", 124 });//运行m3

            //非静态函数的获取及调用
            var m4 = type.GetMethod("M3");
            var val4 = m4.Invoke(C1, null);
            val4 = m4.Invoke(C2, null);
            val4 = m4.Invoke(C3, null);

            var m5 = type.GetMethod("M4", new Type[] { typeof(string) });
            var val5 = m5.Invoke(C1, new object[] { "dtr" });
            val5 = m5.Invoke(C2, new object[] { "dtr" });
            val5 = m5.Invoke(C3, new object[] { "dtr" });

            var m6 = type.GetMethod("M4", new Type[] { typeof(int) });
            var val6 = m6.Invoke(C1, new object[] { 225 });
            val6 = m6.Invoke(C2, new object[] { 225 });
            val6 = m6.Invoke(C3, new object[] { 225 });
        }
View Code

 

方式1

dll文件路径

string dllFilePath=Path.Combine(Application.StartupPath,"Tool","Tool1.dll");

var val = Assembly.LoadFile(dllFile);

无参构造实例   //类的完全限定名(即包括命名空间)
var ass = val.CreateInstance("Tool1.AbsInstance");

带参构造实例(实例带参为(string,int))  new object[] 即为参数,按照参数顺序依次赋值即可

var ass = val.CreateInstance("Tool1.AbsInstance",true, BindingFlags.Default,null,new object[] { "SetStr",10 }, null,null);

AbsTool为已知实体类型

AbsTool tool = (AbsTool)ass;
tool.ShowDialog();

方式2

string dllFile = Path.Combine(Application.StartupPath, "Tool", "Tool2.dll");
var val = Assembly.LoadFile(dllFile);

//类的完全限定名(命名空间.类名)
var val1 = val.GetType("Tool2.AbsInstance");

无参构造函数实例
var val2 = Activator.CreateInstance(val1);

带参构造实例(实例带参为(string,int))  new object[] 即为参数,按照参数顺序依次赋值即可
var val2 = Activator.CreateInstance(val1,new object[] { "strset", 11 });

AbsTool为已知实体类型
AbsTool tool = (AbsTool)val2;
tool.ShowDialog();

 

 

 Assembly.LoadFile与 Assembly.LoadFrom的区别

1、Assembly.LoadFile只载入相应的dll文件,比如Assembly.LoadFile("abc.dll"),则载入abc.dll,假如abc.dll中引用了def.dll的话,def.dll并不会被载入。

Assembly.LoadFrom则不一样,它会载入dll文件及其引用的其他dll,比如上面的例子,def.dll也会被载入。

2、用Assembly.LoadFrom载入一个Assembly时,会先检查前面是否已经载入过相同名字的Assembly,比如abc.dll有两个版本(版本1在目录1下,版本2放在目录2下),程序一开始时载入了版本1,当使用Assembly.LoadFrom("2\\abc.dll")载入版本2时,不能载入,而是返回版本1。Assembly.LoadFile的话则不会做这样的检查,比如上面的例子换成Assembly.LoadFile的话,则能正确载入版本2。

LoadFile:加载指定路径上的程序集文件的内容。LoadFrom: 根据程序集的文件名加载程序集文件的内容。

 

posted @ 2020-07-30 10:52  hwhlg  阅读(364)  评论(0编辑  收藏  举报