• .NET Framework反射总结


    概述

      程序集的反射以及动态的创建类对象,是自动化编程常用的到知识原理,比如插件编程、模板设计模式,都可以采用发射机制动态的去创建实例化对象,实现类的动态加载。这里简单总结下,常用到的Framework反射知识点(泛型和非泛型);.NET框架的三个内置类来使用反射:System.Reflection.Assembly、System.Type和System.Activator;

    • System.Reflection.Assembly类描述了.NET的程序集.在.NET中,程序集是配置单元.对于一个典型的Windows程序,程序集被配置为单一的Win32可执行文件,并且带有特定的附加信息,使之适应.NET运行环境.程序集也可以配置为Win32的DLL(动态链接库),同样需要带有.NET需要的附加信息。System.Reflection.Assembly类可以在运行的时候取得程序集的信息.这些信息包括程序集包含的类型信息。
    • System.Type类描述了类型定义.一个类型声明可以是一个类,接口,数组,结构体,或者枚举.在加载了一个类之后,System.Type类可以被用于枚举该类支持的方法,属性,事件和接口。
    • System.Activator类用于创建一个类的实例。

    程序集Assembly

      程序集的加载和读取方式

    Assembly[] AssbyCustmList = System.AppDomain.CurrentDomain.GetAssemblies();//获取当前那所有程序集
    
    Assembly ResltAss = typeof(IServicePlugin).Assembly;//当前类型所在程序集
    
    Assembly tmp = Assembly.LoadFile(filepath);//文件路径加载

    程序集Type类型

       获取程序集Type类型

    Assembly tmp = Assembly.LoadFile(file);//文件路径加载
    Type[] types = tmp.GetTypes();//获取程序集的所有类型
    Type[]  Items= tmp.GetExportedTypes();//获取程序集公用类型

         判断程序集的属性信息:接口实现、泛型类型

        Type t=GetType();
        Type[] interfaces = t.GetInterfaces();//获取该类型上层实现所有接口
        foreach( Type theInterface in interfaces )
        {
           if (theInterface.FullName == "WinDemo.Core.Iplugin")
           {
                 ret = true;
                 break;
            }
        }
        //t.GetTypes().Where(x => x.GetInterfaces().Count(p => p.FullName == "PluginUnitTestProject.IServicePlugin") >0)//(简写,功能同上)
        Type[] interfaces = t.GetInterface("Iplugin");//获取该类型上层实现接口Iplugin类型 

      判断泛型方式:IsGenericType、GetGenericTypeDefinition()和GetGenericArguments()

        private IEnumerable<Type> GetHandlerTypes<T>() where T : Command
            {
                var handlers = typeof(ICommandHandler<>).Assembly.GetExportedTypes()
                    .Where(x => x.GetInterfaces()
                        .Any(a => a.IsGenericType && a.GetGenericTypeDefinition() == typeof(ICommandHandler<>) ))
                        .Where(h=>h.GetInterfaces()
                            .Any(ii=>ii.GetGenericArguments()
                                .Any(aa=>aa==typeof(T)))).ToList();
    
               
                return handlers;
            }

    程序的创建

    通过程序集的CreateInstance

                Assembly tmp = Assembly.LoadFile(filepth);//文件路径加载
                Type[] types = tmp.GetTypes();
                bool ok = false;
                foreach (Type t in types)
                { 
                    if (IsValidPlugin(t))
                    {
                        IServicePlugin plugin = (IServicePlugin)tmp.CreateInstance(t.FullName);
                //动态加载程序集里面方法,动态调用
                
    MethodInfo medo = t.GetMethod("InvokeTask");medo.Invoke(serple, null);
                    }
                }

    通过Activator.CreateInstance

           ServicePluginAttribute srevic = null;
                foreach (Type itm in TypeItemList)
                {
                    srevic = new ServicePluginAttribute();
                    var serple = Activator.CreateInstance(itm);
             //动态调用程序集里面的方法
             MethodInfo medo = t.GetMethod("InvokeTask");medo.Invoke(serple, null);
            }
  • 相关阅读:
    linux权限及ntfs文件系统权限的知识
    传入字符串,计算字符串长度(用指针实现)
    第一话-简单工厂模式
    Java 多字段排序Comparator(兼容Date,Integer,Doubel,Long)
    关于退运美国转基因玉米含有MRI 162转基因成分的质疑
    Oracle Directory文件夹的知识
    ggplot ggplot2 画图
    Linux Shell文件差集
    linux ps aux 结果解释
    perl常用字符串函数
  • 原文地址:https://www.cnblogs.com/xibei666/p/6931183.html
Copyright © 2020-2023  润新知