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);
        }

    }

結果:android

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,類型對象的準確含義.ios

//經過實列得到類型
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 中,則提供由命名空間限定的類型名稱就足夠了。api

System.TypeInfo提供了實列成員DeclaredNestedTypes和GetDeclaredNestedType定義了類中嵌套的類型.數組

System.Reflection.Assembly 類型提供了實列成員app

GetType  \\string,輸入的類型的全名less

DefinedTypes \\ 返回全部定義的類型的TypeInfo.函數

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

ExportedTypes\\返回全部定義的公共類型ui

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

type對象是輕量級引用,須要更多的瞭解類型自己,必須獲取一個TypeInfo對象this

TypeInfo ti = typeof(ReflectionRef).GetTypeInfo();

 

  • IsPublic
  • IsSealed
  • IsAbstract
  • IsClass
  • IsValueType
  • 另外一些參數返回:
  • Assembly
  • AssemblyQulifiedName
  • FullName
  • Module

3,經過反射構建派生類的層次結構

  • 批量加載程序集---注意,加載程序集的四個要素

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

 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,設計支持加載項的程序.

    Rainbow  在使用過程當中發現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));

                });
        }
相關文章
相關標籤/搜索