当开发插件的时候需要用到反射,在客户端动态加载遍历程序集,并调用每个程序集的方法。

创建一个控制台应用程序,首先设计一个接口:

    public interface ISay
    {
        void SaySth();
    }

在控制台应用程序下创建Plugins文件夹,控制台的可执行文件和所有程序集文件都生成在这里。右键控制台项目--"属性"--"生成",把"输出路径"设置成Plugins文件夹。

创建类库项目Assembly1,添加对控制台项目的引用,并创建实现ISay接口的类:

namespace Assembly1
{
    public class OneSay : ISay
    {

        public void SaySth()
        {
            Console.WriteLine("我来自程序集1");
        }
    }
}

右键类库项目Assembly1--"属性"--"生成",把"输出路径"设置成Plugins文件夹,并生成类库项目Assembly1。

客户端需要找到所有程序集中所有实现ISay接口的类。其基本思路是:
→找到Plugins文件夹下所有dll后缀的文件
→遍历这些文件,根据文件名动态加载程序集
→遍历程序集中实现ISay接口的类型,并保存到ISay类型的集合中
→客户端遍历ISay类型的集合,调用ISay的接口方法

    class Program
    {
        static void Main(string[] args)
        {
            foreach (var say in GetSpeakers())
            {
                say.SaySth();
            }
        }

        static List<ISay> GetSpeakers()
        {
            List<ISay> result = new List<ISay>();

            //获取项目根目录下的Plugins文件夹
            string dir = Directory.GetCurrentDirectory();

            //遍历目标文件夹中包含dll后缀的文件
            foreach (var file in Directory.GetFiles(dir + @"\", "*.dll"))
            {
                //加载程序集
                var asm = Assembly.LoadFrom(file);

                //遍历程序集中的类型
                foreach (var type in asm.GetTypes())
                {
                    //如果是ISay接口
                    if (type.GetInterfaces().Contains(typeof (ISay)))
                    {
                        //创建接口类型实例
                        var isay = Activator.CreateInstance(type) as ISay;

                        if (isay != null)
                        {
                            result.Add(isay);
                        }
                    }
                }
            }
            return result;
        }

再创建一个类库项目Assembly2,添加对控制台项目的引用,并创建实现ISay接口的类:

namespace Assembly2
{
    public class TwoSay : ISay
    {
        public void SaySth()
        {
            Console.WriteLine("我来自程序集2");
        }
    }
}

右键类库项目Assembly2--"属性"--"生成",把"输出路径"设置成Plugins文件夹,并生成类库项目Assembly2。

再次运行控制台项目。

C#使用反射加载多个程序集的更多相关文章

  1. Unity热更新之C#反射加载程序集

    用C#反射加载程序集的方式可以动态的从assetBundle资源包或其他资源包里加载脚本到工程中,即便是原工程中不存在的脚本. 我这里就用加载本地assetBundle的方式来进行讲解了,加载网络上的 ...

  2. 仅反射加载(ReflectionOnlyLoadFrom)的 .NET 程序集,如何反射获取它的 Attribute 元数据呢?

    原文:仅反射加载(ReflectionOnlyLoadFrom)的 .NET 程序集,如何反射获取它的 Attribute 元数据呢? 平时我们获取一个程序集或者类型的 Attribute 是非常轻松 ...

  3. C#.Net 如何动态加载与卸载程序集(.dll或者.exe)0-------通过应用程序域AppDomain加载和卸载程序集

    本博客中以“C#.Net 如何动态加载与卸载程序集(.dll或者.exe)”开头的都是引用莫问奴归处 微软装配车的大门似乎只为货物装载敞开大门,却将卸载工人拒之门外.车门的钥匙只有一把,若要获得还需要 ...

  4. C#.Net 如何动态加载与卸载程序集(.dll或者.exe)2----通过应用程序域AppDomain加载和卸载程序集之后,如何再返回原来的主程序域

    实现目的:动态加载dll,执行完毕之后可以随时卸载掉,并可以替换这些dll,以在运行中更新dll中的类. 其实就是通过应用程序域AppDomain加载和卸载程序集. 在这方面微软有篇文章http:// ...

  5. 使用C#的AssemblyResolve事件动态解析加载失败的程序集

    我们知道反射是 依赖注入 模式的基础,依赖注入要求只在项目中引用定义接口的程序集,而不引用接口实现类的程序集,因为接口实现类的程序集应该是通过反射来动态加载的,这样才能保证接口与其实现类之间的松耦合. ...

  6. .net加载失败的程序集重新加载

    在.net程序中,程序集是Lazy加载的,只有在用的时候才会去加载,当程序集加载失败时,会触发AppDomain.AssemblyResolve的事件,在这个事件中,我们甚至还可以进行补救,从别得地方 ...

  7. 通过应用程序域AppDomain加载和卸载程序集

    微软装配车的大门似乎只为货物装载敞开大门,却将卸载工人拒之门外.车门的钥匙只有一把,若要获得还需要你费一些心思.我在学习Remoting的时候,就遇到一个扰人的问题,就是Remoting为远程对象仅提 ...

  8. 使用C#的AssemblyResolve事件和TypeResolve事件动态解析加载失败的程序集

    我们知道反射是 依赖注入 模式的基础,依赖注入要求只在项目中引用定义接口的程序集,而不引用接口实现类的程序集,因为接口实现类的程序集应该是通过反射来动态加载的,这样才能保证接口与其实现类之间的松耦合. ...

  9. Quartz.net 2.x 学习笔记03-使用反射加载定时任务

    将定时任务信息存储在XML文件中,使用反射加载定时任务 首先新建一个MVC的空站点,使用NuGet添加对Quartz.net和Common.Logging.Log4Net1213的引用,同时使用NuG ...

随机推荐

  1. Python练手之爬虫

    很久没更新博客了,最近自学Python,写个在百度上爬算法题题解的爬虫,第一次写爬虫..纯当练手 慢慢来.. #coding:utf-8 ''' Created on 2016年11月22日 @aut ...

  2. poj 2187 N个点中输出2点的最大距离的平方

    旋转卡壳 Sample Input 40 00 11 11 0Sample Output 2 # include <iostream> # include <cstdio> # ...

  3. 如何查看K8S的网络是否完好

    今天工作中遇到这个问题, 检查从以下几个方面入手. 一,查看各个POD的LOG,如果有错误,则要解决了再继续 二,登陆各个POD之间,互相要能PING通. 三,在物理节点上可以PING通SERVICE ...

  4. day7 socket网络编程

    Python Socket网络编程 Socket是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:它能实现不同主机间的进程间通信,我们网络上各种各样的服务大多都是基于Socket来完成通信的 ...

  5. DotNetOpenAuth实践之搭建验证服务器

    系列目录: DotNetOpenAuth实践系列(源码在这里) DotNetOpenAuth是OAuth2的.net版本,利用DotNetOpenAuth我们可以轻松的搭建OAuth2验证服务器,不废 ...

  6. Playrix Codescapes Cup (Codeforces Round #413, rated, Div. 1 + Div. 2) E - Aquarium decoration 贪心 + 平衡树

    E - Aquarium decoration 枚举两个人都喜欢的个数,就能得到单个喜欢的个数,然后用平衡树维护前k大的和. #include<bits/stdc++.h> #define ...

  7. jenkins远程执行shell

    旧版本: 安装插件 SSH plugin 1. 增加一个domain,点击OK 点击 adding some credentials 填写要远程连接的服务器的用户名和密码(以下例子为连接到91机器的r ...

  8. 把对象转换成JSON形式的html代码

    function formatJson(msg) { var rep = "~"; var jsonStr = JSON.stringify(msg, null, rep) var ...

  9. Sockets CF732E set map

    题目:http://codeforces.com/problemset/problem/732/E 题目大意: 有n台电脑(computer)和m个插座(socket),两者均有一个power值,分别 ...

  10. BZOJ 3172 [Tjoi2013]单词 AC自动机Fail树

    题目链接:[http://www.lydsy.com/JudgeOnline/problem.php?id=3172] 题意:给出一个文章的所有单词,然后找出每个单词在文章中出现的次数,单词用标点符号 ...