原文:https://blog.csdn.net/pengdayong77/article/details/47622235

在.Net 中,程序集(Assembly)中保存了元数据(MetaData)信息,因此就可以通过分析元数据来获取程序集中的内容,比如类,方法,属性等,这大大方便了在运行时去动态创建实例。

反射提供了封装程序集、模块和类型的对象(Type 类型)。可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性。如果代码中使用了属性,可以利用反射对它们进行访问。

主要用途:

  1. 动态加载DLL,实现插件机制。
  2. 实例化DLL中的类型。
  3. 执行后期绑定,访问在运行时创建的类型的方法。

今天我就介绍下后面的两个用途,其实最初的目的只是想根据配置文件中的值创建对应对象。

Dll

先上一段代码,这是要调用的ClassGreenerycn类,它被编译为DllDemo.dll。

    using System;

    namespace DllDemo
{
public class ClassGreenerycn
{
public string Name { get; set; }
public bool IsTest { get; set; }
public void Hello()
{
Console.WriteLine(Name);
}
}
}

很简单的代码,就是一个类中有两个属性,Hello方法会向命令行中输出Name的名称。

使用反射创建Dll中的类实例并调用方法

现在再新建一个命令行的工程,该工程就一个用途,动态加载DllDemo.dll,然后实例化一个Name为Greenerycn,IsTest为True的对象,并调用Hello方法。

详细步骤如下:

1.引用反射的命名空间:

using System.Reflection;

2.动态加载Dll

动态加载Dll有3个函数:

public static Assembly Load(string assemblyString);
  • 该方法传入的是Dll的名字,该Dll必须位于全局缓存GAC中才行,不然会报“System.IO.FileLoadException: 未能加载文件或程序集”的异常。
public static Assembly LoadFile(string path);
  • 这个LoadFile最方便,参数就是dll的路径。
public static Assembly LoadFrom(string assemblyFile);
  • 这个方法也可以,参数同样是dll路径。

3.获取ClassGreenerycn类的类型

var type = asm.GetType("DllDemo.ClassGreenerycn");

注意,这里需要完整的类型名称,包括签名的命名空间。

4.创建该类型的实例

var instance = asm.CreateInstance("DllDemo.ClassGreenerycn");

5.设置属性

type.GetProperty("Name").SetValue(instance, "http://greenerycn.cnblogs.com", null);
type.GetProperty("IsTest").SetValue(instance, true, null);

6.获取Hello方法

var method = type.GetMethod("Hello");

7.调用Hello方法

method.Invoke(instance, null);

8.编译运行

完整的代码

using System.Reflection;

namespace ReflectionDllDemo
{
class Program
{
static void Main(string[] args)
{
var asm = Assembly.LoadFile(@"d:\3_code\DotNet\DllDemo\DllDemo\bin\Debug\DllDemo.dll"); var type = asm.GetType("DllDemo.ClassGreenerycn"); var instance = asm.CreateInstance("DllDemo.ClassGreenerycn"); type.GetProperty("Name").SetValue(instance, "http://greenerycn.cnblogs.com", null);
type.GetProperty("IsTest").SetValue(instance, true, null); var method = type.GetMethod("Hello");
method.Invoke(instance, null);
}
}
}
---------------------
//在外部动态库和本地类继承同一抽象类AbstractHi并实现同一接口interface 的情况下(甚至接口引用相同实体),主要用于加载不同类名,但实际签名相同的方法的类

//实体
public class Person
{
public string Name {get ;set}
}
//1.创建接口
public interface IHi
{
string SayHi();
Person GetPerson();
}
//2.抽象类继承接口
public abstract class AbstractHi : IHi
{
public abstract string SayHi();
public abstract Person GetPerson();
}
-----------------------------------------------
//3.动态库实现(dll文件)
public class DllDemo : AbstractHi
{
public override string SayHi()
{
return "Hi";
}
public override Person GetPerson()
{
var person =new Person ();
Person.Name = "MyName";
return person ;
}
}
------------------------------------------------
//4.加载动态库
/// <summary>
/// 返回操作对象,加载类名包含defaultClass字符串的类
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="defaultClass"></param>
/// <returns></returns>
public static T GetDllDemo<T>(string defaultClass) where T : class
{
try
{
var asm = Assembly.LoadFile(@"d:\3_code\DotNet\DllDemo\DllDemo\bin\Debug\DllDemo.dll");
var dllDemo = (from d in asm.DefinedTypes
where d.BaseType.FullName.Contains(defaultClass)
select d.FullName
).FirstOrDefault();
var type = asm.GetType(dllDemo);
return Activator.CreateInstance(type) as T;
}
catch (Exception ex)
{
throw ex;
}
} //.实例化
public class DllDemoBLL
{
private AbstractHi_DAL
public DllDemoBLL()
{
_DAL = GetDllDemo<AbstractHi>("DllDemo");
}
public string SayHi2()
{
return _DAL. SayHi();
}
public Person GetPerson2()
{
return _DAL. GetPerson();
}
}
//.调用
private DllDemoBLL _BLL = new DllDemoBLL(); public string SayHi3()
{
return _BLL.SayHi2();
//最终返回 "Hi"
}
public Person GetPerson3()
{
return _BLL.GetPerson2();
//最终返回 Person 属性Name=“MyName” 的实体
}
 

C# 反射实现动态加载程序集的更多相关文章

  1. C#动态加载程序集(转)

    C#动态加载程序集 今天在看网络上的一篇关于‘.NET应用自动部署窗体技术’.NET的自动部署技术构造在.NET框架之中,它使得应用程序能够通过HTTP连接从远程服 务器按需下载程序集.有了这个功能, ...

  2. C# 动态加载程序集信息

    本文通过一个简单的实例,来讲解动态加载Dll需要的知识点.仅供学习分享使用,如有不足之处,还请指正. 在设计模式的策略模式中,需要动态加载程序集信息. 涉及知识点: AssemblyName类,完整描 ...

  3. C# 动态加载程序集dll (实现接口)

    一.程序集(接口程序集):LyhInterface.Dll namespace LyhInterface { public interface ILyhInterface { void Run(); ...

  4. .Net Core 通过依赖注入和动态加载程序集实现宿程序和接口实现类库完全解构

    网上很多.Net Core依赖注入的例子代码,例如再宿主程序中要这样写: services.AddTransient<Interface1, Class1>(); 其中Interface1 ...

  5. 应用程序域 System.AppDomain,动态加载程序集

    一.概述 使用.NET建立的可执行程序 *.exe,并没有直接承载到进程当中,而是承载到应用程序域(AppDomain)当中.在一个进程中可以包含多个应用程序域,一个应用程序域可以装载一个可执行程序( ...

  6. Java反射、动态加载(将java类名、方法、方法参数当做参数传递,执行方法)

    需求:将java类名.方法.方法参数当做参数传递,执行方法.可以用java的动态加载实现   反射的过程如下:     第一步:通过反射找到类并创建实例(classname为要实例化的类名,由pack ...

  7. Assembly.Load动态加载程序集而不占用文件 z

    方式一:占用文件的加载 Assembly assembly = Assembly.Load(path); 用上面的方法可以动态的加载到dll,但是用这种方法加载到的dll一直到程序运行结束都是占用的d ...

  8. 关于c#动态加载程序集的一些注意事项

    Assembly下有LoadFile,LoadFrom等方法可以加载程序集. LoadFile只加载你给定路径的那个dll,LoadFrom会自动加载依赖的dll. 如:A依赖B,LoadFile(& ...

  9. asp.net动态加载程序集创建指定类的实例及调用指定方法

    以下类中有三个方法: LoadAssembly:加载指定路径的程序集 GetInstance:根据Type动态获取实例,用泛型接到返回的类型 ExecuteMothod:执行实例中的指定方法 /// ...

随机推荐

  1. Eclipse Debug模式的开启与关闭问题简析_java - JAVA

    文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 默认情况下,eclipse中右键debug,当运行到设置的断点时会自动跳到debug模式下.但由于我的eclipse环境 ...

  2. PageOffice修改注册码升级版本

    java: 删除pageoffice.jar所在目录(一般是WEB-INF/lib)下的license.lic文件(若服务器运行时找不到该文件,可在浏览器地址栏里面通过localhost方式访问pos ...

  3. SpringMVC最新教程IDEA版

    1.servlet项目结构与识别 Idea里带个蓝点的文件夹为tomcat吃的网站内容,idea会通过“Web Resource Directory”来标注,会被打成一个war包 这个文件夹里,MET ...

  4. 华为云服务器centos7.3 安装jdk

    1. 进入oracle官网 https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 服 ...

  5. CSS盒子模型中的Padding属性

    CSS padding 属性 CSS padding 属性定义元素边框与元素内容之间的空白区域,不可见.如果想调整盒子的大小可以调整内容区,内边距,边框. CSS padding 属性定义元素的内边距 ...

  6. Spring Boot文件上传

    一.创建一个简单的包含WEB依赖的SpringBoot项目 二.配置文件上传的文件大小限制 # 上传文件总的最大值spring.servlet.multipart.max-request-size=1 ...

  7. 【BZOJ5092】分割序列(高维前缀和)

    题意:对于一个长度为n的非负整数序列b_1,b_2,...,b_n, 定义这个序列的能量为:f(b)=max{i=0,1,...,n}((b_1 xor b_2 xor...xor b_i)+(b_{ ...

  8. WIN10系统和压缩内存占用磁盘过高的解决方案(亲测有效)

    系统和压缩内存磁盘占用过高的解决方案 最近一段时间玩游戏看视频经常莫名的卡顿,观察发现电脑卡的时候,WIN10进程中的"系统和压缩内存"一项占用了近100%的磁盘空间. 百度搜索到 ...

  9. PHP代码修改后提交,无法立即生效

    今天遇到一个坑爹的问题,就是我修改了PHP代码,提交到网站根目录以后,刷新浏览器居然无法立即生效,差不多得一分钟的样子再去刷新,才会看到更改后的效果. 出现这个问题的原因,是因为手头的项目需要较高的P ...

  10. db2数据库表操作错误SQL0668N Operation not allowed for reason code "1" on table "表". SQLSTATE=57016的解决方法

    错误sql Operation not allowed for reason code "1" on table "MARKET.PURE_USER".. SQ ...