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

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

    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. Centos之关机和重启命令

    shutdown命令 shutdown [选项] 时间 -c:取消前一个关机命令 -h:关机 -r:重启 [root@localhost ~]# date 2017年 06月 21日 星期三 15:4 ...

  2. Effective STL 学习笔记 Item 26: Prefer Iterator to reverse_iterator and const_rever_itertor

    Effective STL 学习笔记 Item 26: Prefer Iterator to reverse_iterator and const_rever_itertor */--> div ...

  3. jenkins Error performing command: git ls-remote -h

    Jenkins新建项目中源码管理使用Git时遇到如下问题: Failed to connect to repository : Error performing command: git ls-rem ...

  4. C#设置窗体中的窗体随主窗体大小变化而变化

    form2 f=new form2(); f.Size=this.Size; f.Location=this.Location; f.showdialog(); 作者:耑新新,发布于  博客园 转载请 ...

  5. Pg168—2题 修改

    package org.hanqi.pn0120; public class JuXing { JuXing(double chang,double kuan) { this.chang=chang; ...

  6. Asp.net Vnext TagHelpers

    概述 本文已经同步到<Asp.net Vnext 系列教程 >中] TagHelpers 是vnext中引入的新功能之一.TagHelper 的作用是类似于发挥在以前版本的 ASP.NET ...

  7. HDU - 4458 计算几何判断点是否在多边形内

    思路:将飞机看成不动的,然后枚举时间看点是否在多边形内部. #include<bits/stdc++.h> #define LL long long #define fi first #d ...

  8. Hive分区和桶的概念

    Hive 已是目前业界最为通用.廉价的构建大数据时代数据仓库的解决方案了,虽然也有 Impala 等后起之秀,但目前从功能.稳定性等方面来说,Hive 的地位尚不可撼动. 其实这篇博文主要是想聊聊 S ...

  9. js根据IP跳转

    <script language="javascript" type="text/javascript" src="http://int.dpo ...

  10. scp和rsync的区别和常用参数

    一.scp 命令 1.scp 是 secure copy 的缩写,用于远程的文件的复制. 2.参数: -r: 递归复制整个目录. 3.实例: scp /home/space/music/1.mp3 u ...