反射之Assembly.Load和Activator的使用(转载)

反射之Assembly.Load和Activator的使用

大家都知道在C#2.0的时候,为了方便调用方法,微软开放了新的功能专门针对于反射,那就是Activator类。那么Activator类和Assembly.Load到底有啥区别呢? 我想网上很多有人解释过了。

Reflection,中文翻译为反射。这是.Net中获取运行时类型信息的方式,.Net的应用程序由几个 部分:‘程序集(Assembly)’、‘模块(Module)’、‘类型(class)’组成,而反射提供一种编程的方式,让程序员可以在程序运行期获 得这几个组成部分的相关信息,例如:Assembly类可以获得正在运行的装配件信息,也可以动态的加载装配件,以及在装配件中查找类型信息,并创建该类 型的实例。Type类可以获得对象的类型信息,此信息包含对象的所有要素:方法、构造器、属性等等,通过Type类可以得到这些要素的信息,并且调用之。 MethodInfo包含方法的信息,通过这个类可以得到方法的名称、参数、返回值等,并且可以调用之。诸如此类,还有FieldInfo、 EventInfo等等,这些类都包含在System.Reflection命名空间下。
在C#中,我们要使用反射,首先要搞清楚以下命名空间中几个类的关系:
System.Reflection命名空间
(1)AppDomain:应用程序域,可以将其理解为一组程序集的逻辑容器I
(2)Assembly:程序集类
(3)Module:模块类
(4)Type:使用反射得到类型信息的最核心的类
他们之间是一种从属关系,也就是说,一个AppDomain可以包含N个Assembly,一个Assembly可以包含N个Module,而一个Module可以包含N个Type.AppDomain这个类我们等下再来讲解。我们先关注Assembly个类,在程序中,如果我们要动态加载一个程序集怎么办呢?有几种方式可以使用,分别是Load,LoadFrom和LoadWithPartialName三个Assembly的静态方法.

 

先来讲解Assembly.Load方法,该方法会有多个重载版本,其中一个就是提供程序集的详细信息,即程序集的标识,包括程序集的名称,版本,区域信息,公有密钥标记,全部都是以一个字符串的形式提供,例如:"MyAssembly,Version=1.0.0.0,culture=zh-CN,PublicKeyToken=47887f89771bc57f”.
那么,使用Assembly.Load加载程序集的顺序是怎样的呢?首先它会去全局程序集缓存查找,然后到应用程序的根目录查找,最后会到应用程序的私有路径查找。
当然,如果你使用的是弱命名程序集,也即只给出程序集的名称,那么这个时候,CLR将不会在程序集上应用任何安全或者部署策略,而且Load也不会到全局缓存程序集中查找程序集。
Assembly.Load("")的使用说明如下;
中间参数并不是命名空间,而是常用的是程序集名称,也就是dll的名称
Assembly.Load (AssemblyName) 在给定程序集的 AssemblyName 的情况下,加载程序集

由 .NET Compact Framework 支持
Assembly.Load (Byte[]) 加载带有基于通用对象文件格式 (COFF) 的图像的程序集,该图像包含已发出的程序集。将该程序集加载到调用方的域。
Assembly.Load (String) 通过给定程序集的长格式名称加载程序集。
由 .NET Compact Framework 支持。
Assembly.Load (AssemblyName, Evidence) 在给定程序集的 AssemblyName 的情况下,加载程序集。使用提供的证据将该程序集加载到调用方的域中。
Assembly.Load (Byte[], Byte[]) 加载带有基于通用对象文件格式 (COFF) 的图像的程序集,该图像包含已发出的程序集。
Assembly.Load (String, Evidence) 通过给定的程序集的显示名称来加载程序集,使用提供的证据将程序集加载到调用方的域中。

Assembly.Load (Byte[], Byte[], Evidence) 加载带有基于通用对象文件格式 (COFF) 的图像的程序集,该图像包含已发出的程序集。

关于反射Assembly.Load("程序集").CreateInstance("命名空间.类")

而不管在哪一层写这段代码其中的("程序集")读取的实际是web层bin文件夹下的dll,也就是说你反射的类的程序集dll在web层的bin下必须有。

注意CreateInstance()一定是命名空间.类名,否则创建的实例为空
Assembly.Load("程序集名")
Assembly.LoadFrom("程序集实际路径")

下面看一个例子说明Activator和Assembly.Load的使用:

我有一个接口 IUserProfiler:

namespace WebApp2010
{
    public interface IUserProfiler
    {
        string GetUserProfiler(string UserId);
    }
}

同事我还有它的实现类:

namespace WebApp2010
{
    public class UserProfilerService: IUserProfiler
    {
        public string GetUserProfiler(string UserId)
        {
            if (UserId == "A001")
                return "Bob";
            else return string.Empty;
        }
    }
}

在展现页面里我用了三种方法来调用这个类:

            Type t = Type.GetType("WebApp2010.UserProfilerService");

            IUserProfiler result = (IUserProfiler)Activator.CreateInstance(t);

            Response.Write(result.GetUserProfiler("A001"));


            IUserProfiler result1 = (IUserProfiler)Activator.CreateInstance(typeof(UserProfilerService));

            Response.Write(result1.GetUserProfiler("A001"));

 

            IUserProfiler result2 = (IUserProfiler)Assembly.Load("WebApp2010").CreateInstance("WebApp2010.UserProfilerService");

            Response.Write(result2.GetUserProfiler("A001"));

应该看出来有啥区别了吧。 Activator相对来说更灵活一些。

 

转载自源地址 百度博客:

http://hi.baidu.com/zbphot/item/30ca2a506f71e3acacc8574c

posted @ 2013-03-15 13:39  I am a guest  阅读(144)  评论(0编辑  收藏  举报