clr via c# 程序集加载和反射集(一)

1,程序集加载---弱的程序集可以加载强签名的程序集,但是不可相反.否则引用会报错!(但是,反射是没问题的)

//获取当前类的Assembly
Assembly.GetEntryAssembly()
//通过Load方法加载程序集
Assembly.Load
//通过LoadFrom加载指定路径名的程序集--可以时url对象.
Assembly LoadFrom(string path)
//只是反射,并确保程序集中的数据不被执行.
ReflectionOnlyLoadFrom()
ReflectionOnlyLoad(string assembly string)

2,发现程序集中定义的类型

class ReflectionRef
    {
        public static void Demo1()
        {
            string AssemblyName = "s7.net, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d5812d469e84c693, processorArchitecture=MSIL";
            Assembly a = Assembly.Load(AssemblyName);
            Display(0, "{0}‘s types:",a.FullName);
            a.ExportedTypes.ToList().ForEach(x => Display(2, "t‘s FullName is {0}", x.FullName));
            Console.WriteLine();
            a = Assembly.GetEntryAssembly();
            Display(0, "{0}‘s types:", a.FullName);
            a.ExportedTypes.ToList().ForEach(x => Display(2, "t‘s FullName is {0}", x.FullName));

        }
        private static void Display(int indent,string Format,params object[] obj)
        {
            Console.Write(new string(‘ ‘, indent * 2));
            Console.WriteLine(Format, obj);
        }

    }

结果:

s7.net, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d5812d469e84c693‘s types:
     t‘s FullName is S7.Net.TcpClientMixins
     t‘s FullName is S7.Net.Conversion
  2,类型对象的准确含义.

//通过实列获得类型
obj.GetType();
//通过Type类的静态函数GetType()
public static Type GetType (string typeName);//必须是FullName
//是否抛出异常和忽略大小写.
public static Type GetType (string typeName, bool throwOnError, bool ignoreCase);
//
参数
typeName
String

要获取的类型的程序集限定名称。 请参阅 AssemblyQualifiedName。 如果该类型位于当前正在执行的程序集中或者 Mscorlib.dll 中,则提供由命名空间限定的类型名称就足够了。

System.TypeInfo提供了实列成员DeclaredNestedTypes和GetDeclaredNestedType定义了类中嵌套的类型.

System.Reflection.Assembly 类型提供了实列成员

GetType  \\string,输入的类型的全名

DefinedTypes \\ 返回所有定义的类型的TypeInfo.

public virtual System.Collections.Generic.IEnumerable<System.Reflection.TypeInfo> DefinedTypes { get; }

ExportedTypes\\返回所有定义的公共类型

public virtual System.Collections.Generic.IEnumerable<Type> ExportedTypes { get; }

type对象是轻量级引用,需要更多的了解类型本身,必须获取一个TypeInfo对象

TypeInfo ti = typeof(ReflectionRef).GetTypeInfo();
  • IsPublic
  • IsSealed
  • IsAbstract
  • IsClass
  • IsValueType
  • 另一些参数返回:
  • Assembly
  • AssemblyQulifiedName
  • FullName
  • Module

3,通过反射构建派生类的层次结构

  • 批量加载程序集---注意,加载程序集的四个要素

{Name{0},PublicKeyToken={1},version={2},Culture={3}}

 private static void LoadAssemblies()
        {
            String[] assemblies =
            {
            "System,                    PublicKeyToken={0}",
            "System.Core,               PublicKeyToken={0}",
            "System.Data,               PublicKeyToken={0}",
            "System.Design,             PublicKeyToken={1}",
            "System.DirectoryServices,  PublicKeyToken={1}",
            "System.Drawing,            PublicKeyToken={1}",
            "System.Drawing.Design,     PublicKeyToken={1}",
            "System.Management,         PublicKeyToken={1}",
            "System.Messaging,          PublicKeyToken={1}",
            "System.Runtime.Remoting,   PublicKeyToken={0}",
            "System.Security,           PublicKeyToken={1}",
            "System.ServiceProcess,     PublicKeyToken={1}",
            "System.Web,                PublicKeyToken={1}",
            "System.Web.RegularExpressions, PublicKeyToken={1}",
            "System.Web.Services,       PublicKeyToken={1}",
            "System.Windows.Forms,      PublicKeyToken={0}",
            "System.Xml,                PublicKeyToken={0}",
            };

            String EcmaPublicKeyToken = "b77a5c561934e089";
            String MSPublicKeyToken = "b03f5f7f11d50a3a";

            // Get the version of the assembly containing System.Object
            // We‘ll assume the same version for all the other assemblies
            Version version = typeof(System.Object).Assembly.GetName().Version;

            // Explicitly load the assemblies that we want to reflect over
            foreach (String a in assemblies)
            {
                String AssemblyIdentity =
                   String.Format(a, EcmaPublicKeyToken, MSPublicKeyToken) +
                      ", Culture=neutral, Version=" + version;
                Assembly.Load(AssemblyIdentity);//在AppDomain中加载程序集
            }
        }
public static void Demo2()
        {
            Assembly[] oldAssembly = AppDomain.CurrentDomain.GetAssemblies();//未加载程序集时的app Domain中的程序集

            LoadAssemblies();//加载程序集
            var newAssemblyName = (from a in AppDomain.CurrentDomain.GetAssemblies()//获取在原程序集中的程序集
                              where Array.IndexOf(oldAssembly, a) >= 0
                              orderby a.FullName
                              select a.FullName).ToArray();

            Array.ForEach<string>(newAssemblyName, x => Display(3, x));//打印原程序集
            Console.WriteLine("Compare Assemblys end");

            var allTypes =
                (from a in AppDomain.CurrentDomain.GetAssemblies()
                 from t in a.ExportedTypes
                 where typeof(MemberInfo).GetTypeInfo().IsAssignableFrom(t.GetTypeInfo())//获取所有派生自Exception的类型.
                 orderby t.Name
                 select t).ToArray();
            Display(0, WalkInheritanceHierachy(new StringBuilder(), 0, typeof(MemberInfo), allTypes).ToString());//迭代打印这些类型.
        }
  • 迭代查找派生关系
private static StringBuilder WalkInheritanceHierachy(StringBuilder sb,int indent,Type baseType,IEnumerable<Type> allTypes)//迭代打印函数
        {
            string spaces = new string(‘ ‘, indent * 3);//前缀空格
            sb.AppendLine(spaces + baseType.FullName);//添加基类的全名,新一行.
            foreach(var t in allTypes)
            {
                if (t.GetTypeInfo().BaseType != baseType) continue;//如果这个类不是另一个类的基列,继续.
                WalkInheritanceHierachy(sb, indent + 1, t, allTypes);//如果找到某个类是派生类,则将这个类作为基类,去查找新的派生类.
            }
            return sb;
        }
  • 结果:

System.Reflection.MemberInfo
    System.Reflection.EventInfo
       System.Runtime.InteropServices.ComAwareEventInfo
    System.Reflection.FieldInfo
       System.Reflection.Emit.FieldBuilder
    System.Reflection.MethodBase
       System.Reflection.ConstructorInfo
          System.Reflection.Emit.ConstructorBuilder
       System.Reflection.MethodInfo
          System.Reflection.Emit.DynamicMethod
          System.Reflection.Emit.MethodBuilder
    System.Reflection.PropertyInfo
       System.Reflection.Emit.PropertyBuilder
    System.Type
       System.Reflection.TypeInfo
          System.Reflection.Emit.EnumBuilder
          System.Reflection.Emit.GenericTypeParameterBuilder
          System.Reflection.Emit.TypeBuilder
          System.Reflection.TypeDelegator

4,BindingFlags

字段

CreateInstance 512
创建类的实列,Invoke类的实列调用类的构造器时使用.

DeclaredOnly 2
指定当前类上面声明的成员

Default 0
指定未定义任何绑定标志。

DoNotWrapExceptions 33554432  
ExactBinding 65536
未知...

FlattenHierarchy 64
指定应返回层次结构往上的公共成员和受保护静态成员。. 静态成员包括字段、方法、事件和属性。. 不支持嵌套类型。

GetField 1024
指定应返回指定字段的值。此标志会传递给 InvokeMember
方法以获取字段值。

GetProperty 4096
指定应返回指定属性的值。此标志会传递给 InvokeMember 方法以调用属性

IgnoreCase 1
指定在绑定时不应考虑成员名称的大小写。

IgnoreReturn 16777216
在 COM
互操作中用于指定可以忽略成员的返回值。

Instance 4
指定实例成员要包括在搜索中。

InvokeMethod 256
指定要调用的方法。非构造器

此标志会传递给 InvokeMember 方法以调用方法。

NonPublic 32
指定非公共成员要包括在搜索中。

OptionalParamBinding 262144
返回其参数计数与提供的参数数量匹配的成员集。

此绑定标志用于参数具有默认值的方法和使用变量参数 (varargs)
的方法。此标志只应与 InvokeMember(String, BindingFlags, Binder, Object,
Object[], ParameterModifier[], CultureInfo, String[])
结合使用。
使用默认值的参数仅在省略了尾随参数的调用中使用。Parameters with default values
are used only in calls where trailing arguments are omitted. 它们必须是位于最后面的参数。They must be the last
arguments.

Public 16
指定公共成员要包括在搜索中。

PutDispProperty 16384
指定应调用 COM 对象上的 PROPPUT 成员。

PutRefDispProperty 32768
指定应调用 COM 对象上的 PROPPUTREF 成员。

SetField 2048
指定应设置指定字段的值。

SetProperty 8192
指定应设置指定属性的值。

Static 8
指定静态成员要包括在搜索中。

SuppressChangeType 131072
未实现。

public class BindingFlagsRef
    {
        public static void Go()
        {
            // BindingFlags.InvokeMethod
            // Call a static method.
            Type t = typeof(TestClass);

            Console.WriteLine();
            Console.WriteLine("Invoking a static method.");
            Console.WriteLine("-------------------------");
            t.InvokeMember("SayHello", BindingFlags.InvokeMethod | BindingFlags.Public |//调用类的静态方法.注意Binder=null,Target=null
                BindingFlags.Static, null, null, new object[] { });

            // BindingFlags.InvokeMethod
            // Call an instance method.
            TestClass c = new TestClass();
            Console.WriteLine();
            Console.WriteLine("Invoking an instance method.");
            Console.WriteLine("----------------------------");
            c.GetType().InvokeMember("AddUp", BindingFlags.InvokeMethod, null, c, new object[] { });//调用实列的方法,注意,Target=c;
            c.GetType().InvokeMember("AddUp", BindingFlags.InvokeMethod, null, c, new object[] { });//调用实列的方法,注意,Target=c;

            // BindingFlags.InvokeMethod
            // Call a method with parameters.
            object[] args = new object[] { 100.09, 184.45 };
            object result;
            Console.WriteLine();
            Console.WriteLine("Invoking a method with parameters.");
            Console.WriteLine("---------------------------------");
            result = t.InvokeMember("ComputeSum", BindingFlags.InvokeMethod , null, null, args);//调用带参数的方法.
            Console.WriteLine("{0} + {1} = {2}", args[0], args[1], result);

            // BindingFlags.GetField, SetField
            Console.WriteLine();
            Console.WriteLine("Invoking a field (getting and setting.)");
            Console.WriteLine("--------------------------------------");
            // Get a field value.
            result = t.InvokeMember("Name", BindingFlags.GetField, null, c, new object[] { });//获取和设定字段.
            Console.WriteLine("Name == {0}", result);
            // Set a field.
            t.InvokeMember("Name", BindingFlags.SetField, null, c, new object[] { "NewName" });
            result = t.InvokeMember("Name", BindingFlags.GetField, null, c, new object[] { });
            Console.WriteLine("Name == {0}", result);

            Console.WriteLine();
            Console.WriteLine("Invoking an indexed property (getting and setting.)");
            Console.WriteLine("--------------------------------------------------");
            // BindingFlags.GetProperty
            // Get an indexed property value.
            int index = 3;
            result = t.InvokeMember("Item", BindingFlags.GetProperty, null, c, new object[] { index });//获取索引器的值.
            Console.WriteLine("Item[{0}] == {1}", index, result);
            // BindingFlags.SetProperty
            // Set an indexed property value.
            index = 3;
            t.InvokeMember("Item", BindingFlags.SetProperty, null, c, new object[] { index, "NewValue" });//设定索引器的值.
            result = t.InvokeMember("Item", BindingFlags.GetProperty, null, c, new object[] { index });
            Console.WriteLine("Item[{0}] == {1}", index, result);

            Console.WriteLine();
            Console.WriteLine("Getting a field or property.");
            Console.WriteLine("----------------------------");
            // BindingFlags.GetField
            // Get a field or property.
            result = t.InvokeMember("Name", BindingFlags.GetField | BindingFlags.GetProperty, null, c,
                new object[] { });
            Console.WriteLine("Name == {0}", result);//获取属性或者字段的对象.
            // BindingFlags.GetProperty
            result = t.InvokeMember("Value", BindingFlags.GetField | BindingFlags.GetProperty, null, c,
                new object[] { });//获取属性或者字段的对象.
            Console.WriteLine("Value == {0}", result);

            Console.WriteLine();
            Console.WriteLine("Invoking a method with named parameters.");
            Console.WriteLine("---------------------------------------");
            // BindingFlags.InvokeMethod
            // Call a method using named parameters.
            object[] argValues = new object[] { "Mouse", "Micky" };
            String[] argNames = new String[] { "lastName", "firstName" };
            t.InvokeMember("PrintName", BindingFlags.InvokeMethod, null, null, argValues, null, null,//指定Named类型的方法.
                argNames);

            Console.WriteLine();
            Console.WriteLine("Invoking a default member of a type.");
            Console.WriteLine("------------------------------------");
            // BindingFlags.Default
            // Call the default member of a type.
            Type t3 = typeof(TestClass2);
            t3.InvokeMember("", BindingFlags.InvokeMethod | BindingFlags.Default, null, new TestClass2(),
                new object[] { });//利用特性MemberDefault,和反射配合指定使用方法.当前是Print.

            // BindingFlags.Static, NonPublic, and Public
            // Invoking a member with ref parameters.
            Console.WriteLine();
            Console.WriteLine("Invoking a method with ref parameters.");
            Console.WriteLine("--------------------------------------");
            MethodInfo m = t.GetMethod("Swap");
            args = new object[2];
            args[0] = 1;
            args[1] = 2;
            //m.Invoke(new TestClass(), args);//和调用有参的形式一样,这是新的办法
            t.InvokeMember("Swap", BindingFlags.InvokeMethod, null, new TestClass(), args);//这是通过type来调用.
            Console.WriteLine("{0}, {1}", args[0], args[1]);

            // BindingFlags.CreateInstance
            // Creating an instance with a parameterless constructor.
            Console.WriteLine();
            Console.WriteLine("Creating an instance with a parameterless constructor.");
            Console.WriteLine("------------------------------------------------------");
            object cobj = t.InvokeMember("TestClass", BindingFlags.Public |//注意3个BindingFlags的应用.
                BindingFlags.Instance | BindingFlags.CreateInstance,
                null, null, new object[] { });//创建类的实列的另外一个办法.
            Console.WriteLine("Instance of {0} created.", cobj.GetType().Name);

            // Creating an instance with a constructor that has parameters.
            Console.WriteLine();
            Console.WriteLine("Creating an instance with a constructor that has parameters.");
            Console.WriteLine("------------------------------------------------------------");
            cobj = t.InvokeMember("TestClass", BindingFlags.Public |//创建有参的构造器,并且返回实列.
                BindingFlags.Instance | BindingFlags.CreateInstance,
                null, null, new object[] { "Hello, World!" });
            Console.WriteLine("Instance of {0} created with initial value ‘{1}‘.", cobj.GetType().Name,
                cobj.GetType().InvokeMember("Name", BindingFlags.GetField, null, cobj, null));

            // BindingFlags.DeclaredOnly
            Console.WriteLine();
            Console.WriteLine("DeclaredOnly instance members.");
            Console.WriteLine("------------------------------");
            System.Reflection.MemberInfo[] memInfo =
                t.GetMembers(BindingFlags.DeclaredOnly | BindingFlags.Instance |//考虑在本类中创建(非继承,实列,公共)的成员集合.
                BindingFlags.Public);
            for (int i = 0; i < memInfo.Length; i++)
            {
                Console.WriteLine(memInfo[i].Name);
            }

            // BindingFlags.IgnoreCase
            Console.WriteLine();
            Console.WriteLine("Using IgnoreCase and invoking the PrintName method.");
            Console.WriteLine("---------------------------------------------------");
            t.InvokeMember("printname", BindingFlags.IgnoreCase | BindingFlags.Static |//忽略大小写
                BindingFlags.Public | BindingFlags.InvokeMethod, null, null, new object[]
                {"Brad","Smith"});

            // BindingFlags.FlattenHierarchy
            Console.WriteLine();
            Console.WriteLine("Using FlattenHierarchy to get inherited static protected and public members.");
            Console.WriteLine("----------------------------------------------------------------------------");
            FieldInfo[] finfos = typeof(MostDerived).GetFields(BindingFlags.NonPublic | BindingFlags.Public |//NoPublic是Protected对象.
                  BindingFlags.Static | BindingFlags.FlattenHierarchy);//返回受保护静态成员.
            foreach (FieldInfo finfo in finfos)
            {
                Console.WriteLine("{0} defined in {1}.", finfo.Name, finfo.DeclaringType.Name);//DeclaringType...成员所定义的Type
            }

            Console.WriteLine();
            Console.WriteLine("Without FlattenHierarchy.");
            Console.WriteLine("-------------------------");
            finfos = typeof(MostDerived).GetFields(BindingFlags.NonPublic | BindingFlags.Public |
                  BindingFlags.Static);
            foreach (FieldInfo finfo in finfos)
            {
                Console.WriteLine("{0} defined in {1}.", finfo.Name, finfo.DeclaringType.Name);
            }
        }

    }
    public class TestClass
    {
        public String Name;
        private Object[] values = new Object[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

        public Object this[int index]
        {
            get
            {
                return values[index];
            }
            set
            {
                values[index] = value;
            }
        }

        public Object Value
        {
            get
            {
                return "the value";
            }
        }

        public TestClass() : this("initialName") { }
        public TestClass(string initName)
        {
            Name = initName;
        }

        int methodCalled = 0;

        public static void SayHello()
        {
            Console.WriteLine("Hello");
        }

        public void AddUp()
        {
            methodCalled++;
            Console.WriteLine("AddUp Called {0} times", methodCalled);
        }

        public static double ComputeSum(double d1, double d2)
        {
            return d1 + d2;
        }

        public static void PrintName(String firstName, String lastName)
        {
            Console.WriteLine("{0},{1}", lastName, firstName);
        }

        public void PrintTime()
        {
            Console.WriteLine(DateTime.Now);
        }

        public void Swap(ref int a, ref int b)
        {
            int x = a;
            a = b;
            b = x;
        }

    }
    [DefaultMemberAttribute("PrintTime")]
    public class TestClass2
    {
        public void PrintTime()
        {
            Console.WriteLine(DateTime.Now);
        }
    }

    public class Base
    {
        static int BaseOnlyPrivate = 0;
        protected static int BaseOnly = 0;
    }
    public class Derived : Base
    {
        public static int DerivedOnly = 0;
    }
    public class MostDerived : Derived { }

上面的列子枚举了差不多的一些反射调用一个类中的方法或者字段或者其他的一些用法

5,Binder-----从候选者列表中选择一个成员,并执行实参类型到形参类型的类型转换,需要实现派生

Binder用来自定义选择匹配的方法,字段等...一般不用,或者使用Type.DefaultBinder使用.

6,构造类的实列

通过反射构造类的实列常用方法:

public static void CallCreateObjectByReflection()
        {
            //方法1,使用createInstance--type方法.
            Type t = typeof(TestClass);
            TestClass t1 = (TestClass)Activator.CreateInstance(t, new object[] {  });
            Display(0, t1.Name);
            //方法2,使用程序集的方法,第一个参数可以是null,当前程序集,或者是Assembly.GetEnterAssembly.ToString(),返回程序集的全名.
            var t2 = (TestClass)Activator.CreateInstance(null, typeof(TestClass).FullName).Unwrap();
            Display(0, Assembly.GetEntryAssembly().ToString());
            Display(0, t2.Name);
            //方法3,使用CreateInstanceFrom生成.
            var path = Assembly.GetEntryAssembly().CodeBase;
            var t3 = (TestClass)Activator.CreateComInstanceFrom(path, typeof(TestClass).FullName).Unwrap();
            Display(0, "path is {0},type is {1}", path, t3);
            //方法4,使用AppDomain的CreateInstance;注意,如果是另外的appDomain则需要类型是MarshalRefObject的派生类,或者可序列化对象.
            AppDomain ad0 = AppDomain.CreateDomain("Ad0");
            var t4=AppDomain.CurrentDomain.CreateInstanceFromAndUnwrap(path, typeof(TestClass).FullName);
            Display(0, "path is {0},type is {1}", path, t4);
            //方法5,使用InVokeMember调用构造器.
            var t5 = (TestClass)t.InvokeMember("", BindingFlags.Public | BindingFlags.Instance | BindingFlags.CreateInstance, null, null, null);
            Display(0, t5.Name);
            //方法6,使用ConstructorInfo,其实类似上面的
            ConstructorInfo ci = t.GetConstructor(new Type[] { typeof(string) });
            var t6=(TestClass)ci.Invoke(new object[] { "new Constructor" });
            Display(0, t6.Name);
            //方法7,数组类型创建实列
            Array t7 = Array.CreateInstance(t, 10);
            for(int i=0;i<t7.Length;i++)
            {
                t7.SetValue(new TestClass(i.ToString()), i);
            }
            int count=0;
            Array.ForEach<TestClass>((TestClass[])t7, x => Display(count++, x.Name));
            //方法7_1,另外一个方法创建数组的实列.
            Type t71 = t.MakeArrayType();
            var t72 =(TestClass[]) Activator.CreateInstance(t71, new object[] { 10 });
            Display(0, t72.Length.ToString());

            //方法8,委托类型创建实列
            MethodInfo mi = t.GetMethod("AddUp");
            var t8 = new TestClass();
            Delegate d = Delegate.CreateDelegate(typeof(Action), t8, mi);
            d.DynamicInvoke();
            d.DynamicInvoke();

            //方法9,构造泛型实列
            Type openType = typeof(Dictionary<,>);//首先创建openType
            Type closeType = openType.MakeGenericType(typeof(string),typeof(string));//创建封闭Type
            Type ListOpenType = typeof(List<>);//创建新的OpenType
            Type ListCloseType = ListOpenType.MakeGenericType(closeType);//创建复合的封闭对象
            object o = Activator.CreateInstance(ListCloseType);//创建类型对象的实列.
            Display(0, o.ToString());

        }

    }

7,设计支持加载项的程序.

  在使用过程中发现System.IO.FileLoadException错误,的原因为:

  • 如果某个类是强名称,那么所有它引用的类也必须都是强名称.

我因为忘记给HostSDK进行强名称设定,所以出错.HostSDK进行之后,AddIn也要进行.

1,设计接口类:

//HostSDK.cs
using System;

namespace Winteliect.HostSDK
{
	public interface IAddin
	{
		string DoSomeThing(Int32 x);

	}

}

2,设计接口实现类

//AddInTypes.cs
using System;
using Winteliect.HostSDK;

namespace AddInTypes
{
	public sealed class AddIn_A:IAddin
	{
		public AddIn_A(){}
		public string DoSomeThing(Int32 x)
		{
			return "AddIn_A:"+x.ToString();
		}
	}
	public sealed class AddIn_B:IAddin
	{
		public AddIn_B(){}
		public string DoSomeThing(Int32 x)
		{
			return "AddIn_B:"+(2*x).ToString();
		}
	}
}

3,进行编译dll

  • sn -k host.snk
  • csc.exe /out:HostSDK.dll /t:library /keyfile:host.snk HostSDK.cs---生成HostSDK.dll
  • csc.exe /out:AddInTypes.dll /t:library /r:HostSDK.dll /keyfile:host.snk AddInTypes.cs---生成AddInTypes.dll

4,在程序中使用

public static void DynamicLoadDemo()
        {

            string path = Assembly.GetExecutingAssembly().Location;//获取.exe的详细路径
            string AddInDir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);//获取.exe的目录.../Debug
            var dlls = Directory.EnumerateFiles(AddInDir, "*.dll");//
            var types =
                (from file in dlls
                let asb = Assembly.LoadFrom(file)
                from t in asb.ExportedTypes
                where t.IsPublic && t.IsClass && (typeof(IAddin).GetTypeInfo().IsAssignableFrom(t.GetTypeInfo()))
                select t).ToList();//获取有该接口的类.

            types.ForEach(//创建类的实列并且工作.
                x =>
                {
                    IAddin t = (IAddin)Activator.CreateInstance(x);
                    Display(0,t.DoSomeThing(10));

                });
        }

原文地址:https://www.cnblogs.com/frogkiller/p/12310395.html

时间: 2024-10-17 21:02:59

clr via c# 程序集加载和反射集(一)的相关文章

clr via c# 程序集加载和反射(2)

查看,clr via c# 程序集加载和反射(1) 8,发现类型的成员: 字段,构造器,方法,属性,事件,嵌套类型都可以作为类型成员.其包含在抽象类MemberInfo中,封装了所有类型都有的一组属性. MemeberInfo的派生列表: System.Reflection.MemberInfo    System.Reflection.EventInFo System.Reflection.FieldInfo    System.Reflection.MethodBase          

第23章 程序集加载和反射

程序集加载和反射,实现了在编译时对一个类型一无所知的情况下,如何在运行时发现类型的信息,创建类型的实例以及访问类型的成员.显现的功能以及效果是十分强大的,比如使用第三方提供的程序集,以及创建动态可扩展应用程序. 23.1 程序集加载 JIT编译器在将方法的IL代码编译成本地代码时,会查看IL代码中引用了哪些类型.在运行时,JIT编译器查看元数据表TypeRef和AssemblyRef来确定哪一个程序集定义了所引用的类型.在AssemblyRef元数据表的记录项中,包含了构成程序集强名称的各个部分

CLR中的程序集加载

本次来讨论一下基于.net平台的CLR中的程序集加载的机制: [注:由于.net已经开源,可利用vs2015查看c#源码的具体实现] 在运行时,JIT编译器利用程序集的TypeRef和AssemblyRef元数据表来确定哪一个程序集定义了所引用的类型.在AssemblyRef元数据表的记录项中,包含构成程序集的强名称的各个部分.JIT编译器获取包括名称(无扩展名和路径).版本.语言文化和公钥标记,将这些连接成一个字符串.JIT编译器将该标识匹配的一个程序集加载到AppDomain中.] CLR内

程序集加载与反射(二):实例篇

目录: 上篇:程序集加载与反射(一):基础篇 Demo:下载 一.Demo 下面这个Demo,使用了策略模式模仿了一下插件机制.我们举个一邮件发送的例子: 1.一个策略类库:Strategy,里面定义了邮件需要实现的接口:IEmailStrategy. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespa

程序集加载与反射

目录 程序集加载 获取类型信息 构造类型实例 通过反射发现成员 调用成员 一.程序集加载 Load方法:CLR通过调用System.Rreflection.Assemblly类的静态方法来显示加载程序集. public static Assembly Load(AssemblyName assemblyRef); public static Assembly Load(string assemblyString); LoadFrom方法:同样我们可以使用 远程加载程序集.此方法首先打开程序集,并

第二十三章 程序集加载和反射

目录: 23.1 程序集加载 23.2 使用反射构建动态可扩展应用程序 23.3 反射的性能 23.4 设计支持加载项的应用程序 23.5 使用反射发现类型的成员 23.1 程序集加载 JIT编译器将方法的IL代码编译成本机代码时,会查看IL代码中引用了哪些类型.在运行时,JIT编译器利用程序集的TypeRef和AssemblyRef元数据表来确定哪一个程序集定义了所有引用的类型. 通过Assembly的Load方法加载程序集. 23.2 使用反射构建动态可扩展应用程序 23.3 反射的性能 2

程序集加载和反射

一.程序集加载 1,根据程序集名称查找程序集 public class Assembly { public static Assembly Load(AssemblyName assemblyRef); public static Assembly Load(string assemblyString); //未列出不常用的Load重载 } Assembly.Load("ConsoleApplication2");, 2,根据程序集文件路径名(包含扩展名)查找程序集 public cl

程序集加载与反射(二):实战篇

目录: 上篇:http://www.cnblogs.com/sunchong/p/4550476.html Demo 一.Demo 下面这个Demo,使用了策略模式模仿了一下插件机制.我们举个一邮件发送的例子: 1.一个策略类库:Strategy,里面定义了邮件需要实现的接口:IEmailStrategy. using System; using System.Collections.Generic; using System.Linq; using System.Text; using Sys

第一节:程序集加载

我们知道JIT编译器将方法的IL代码编译成本地代码时,会查看IL代码中引用了哪些类型.在运行时,JIT编译器利用程序集的TypeRef和AssemblyRef元数据表来确定哪一个程序集定义了所引用的类型.在AssemblyRef元数据表的记录项中,包含了构成程序集强名称的各个部分.JIT编译器获取所有这些部分,包括名称(无扩展名和路径).版本.语言文化和公钥标记,并把它连接成一个字符串.然后,JIT编译器尝试将与该标识匹配的一个程序集加载到AppDomain中(如果还没有加载的话).如果被加载的