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

MSDN解释如下:

反射提供了封装程序集、模块和类型的对象(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);
        }
    }
}

C#反射动态创建实例并调用方法的更多相关文章

  1. StructureMap.dll 中的 GetInstance 重载 + 如何利用 反射动态创建泛型类

    public static T GetInstance<T>(ExplicitArguments args); // // Summary: // Creates a new instan ...

  2. Vue中通过Vue.extend动态创建实例

    Vue中通过Vue.extend动态创建实例 在Vue中,如果我们想要动态地来控制一个组件的显示和隐藏,比如通过点击按钮显示一个对话框或者弹出一条信息.我们通常会提前写好这个组件,然后通过v-if = ...

  3. Linux下C++动态加载so 调用方法

    Windows 下的C++动态加载DLL调用方法 文献参考 http://man7.org/linux/man-pages/man0/dlfcn.h.0p.html http://man7.org/l ...

  4. .Net 中的反射(动态创建类型实例) - Part.4

    动态创建对象 在前面节中,我们先了解了反射,然后利用反射查看了类型信息,并学习了如何创建自定义特性,并利用反射来遍历它.可以说,前面三节,我们学习的都是反射是什么,在接下来的章节中,我们将学习反射可以 ...

  5. .Net 中的反射(动态创建类型实例)

    动态创建对象 在前面节中,我们先了解了反射,然后利用反射查看了类型信息,并学习了如何创建自定义特性,并利用反射来遍历它.可以说,前面三节,我们学习的都是反射是什么,在接下来的章节中,我们将学习反射可以 ...

  6. WCF 动态调用(动态创建实例接口)

    很多时候,服务地址都不止一个的,这个时候就要动态去配置地址.配置Web.config,很麻烦 下面就看看怎样实现动态调用WCF. 首先看看动态创建服务对象的代码: using System; usin ...

  7. OC 反射-->动态创建类

    系统方法 NSLog(@"%s", __func__); //打印出类的方法名称,如: //打印结果:2018-02-22 10:52:15.394575+0800 DemoRun ...

  8. 动态创建TeeChart的简便方法

    最近在项目中使用Teechart ocx版本替换了labview的老版本控件,显示效果和效率均有提高,但是却遇到多线程下报access violation的问题. 翻遍大小论坛,最后在官网论坛找到相同 ...

  9. .Net Core利用反射动态加载类库的方法(解决类库不包含Nuget依赖包的问题)

    在.Net Framework时代,生成类库只需将类库项目编译好,然后拷贝到其他项目,即可引用或动态加载,相对来说,比较简单.但到了.Net Core时代,动态加载第三方类库,则稍微麻烦一些. 一.类 ...

随机推荐

  1. web添加学生信息(首发web)

    程序思路,先在JSP上画好页面,然后再创建一Servlet文件用于判断在网页上操作是否正确,还需要与数据库相连接,用DBUtile文件连接数据库,用Dao层来实现数据的增加,用Service来服务于D ...

  2. vue-cli 引入 axios 并全局配置axios

    步骤一:vue add axios (向项目添加axios) 步骤二:在main.js 中 修改 如图 步骤三:在组件使用时,直接 this.$http.get().then() 即可......

  3. 报错:required string parameter XXX is not present

    报错:required string parameter XXX is not present 不同工具发起的get/delete请求,大多数不支持@RequestParam,只支持@PathVari ...

  4. Luogu P4331 [BOI2004]Sequence 数字序列 (左偏树论文题)

    清晰明了%%% Fairycastle的博客 个人习惯把size什么的存在左偏树结点内,这样在外面好写,在里面就是模板(只用修改update). 可以对比一下代码(好像也差不多-) MY CODE # ...

  5. node压缩文件

  6. 【Python之路】特别篇--Python装饰器

    前情提要 1. 作用域 在python中,函数会创建一个新的作用域.python开发者可能会说函数有自己的命名空间,差不多一个意思.这意味着在函数内部碰到一个变量的时候函数会优先在自己的命名空间里面去 ...

  7. CTS添加新测试用例步骤

    一.CTS添加新测试用例: 前言: google源代码中的cts测试用例集目录为:source_android4.2/cts/tests/tests/ (source_android4.2表示andr ...

  8. hdu 5831 Rikka with Parenthesis II 括号匹配+交换

    Rikka with Parenthesis II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  9. 顺序表应用4-2:元素位置互换之逆置算法(数据改进)(SDUT 3663)

    Problem Description 一个长度为len(1<=len<=1000000)的顺序表,数据元素的类型为整型,将该表分成两半,前一半有m个元素,后一半有len-m个元素(1&l ...

  10. Centos7 内核升级及删除无用内核

    导入key rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org 安装elrepo的yum源 rpm -Uvh http://www.e ...