注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

天涯倦客的博客

祝福你朋友永远快乐!

 
 
 

日志

 
 

C# 反射中Assembly.Load及Assembly.Load.CreateInstance  

2011-02-24 13:43:55|  分类: C# |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

C#中,我们要使用反射,首先要搞清楚以下命名空间中几个类的关系
System.Reflection
命名空间

(1)
  AppDomain:应用程序域,可以将其理解为一组程序集的逻辑容器
(2)
  Assembly:程序集类
(3)
  Module:模块类
(4)
  Type:使用反射得到类型信息的最核心的类
他们之间是一种从属关系,也就是说,一个AppDomain可以包含NAssembly,一个Assembly可以包含NModule,而一个Module可以包含NType. AppDomain这个类我们等下再来讲解。我们先关注Assembly个类,在程序中,如果我们要动态加载一个程序集怎么办呢?有几种方式可以使用,分别是Load,LoadFromLoadWithPartialName三个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的情况下,加载程序集。
 
 
.NETCompactFramework支持。

  Assembly.Load(Byte[])
加载带有基于通用对象文件格式(COFF)的图像的程序集,该图像包含已发出的程序集。将该程序集加载到调用方的域。 
  Assembly.Load(String)
通过给定程序集的长格式名称加载程序集。
 
.NETCompactFramework支持。

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

关于反射Assembly.Load("程序集").CreateInstance("命名空间.")
而不管在哪一层写这段代码其中的("程序集")读取的实际是webbin文件夹下的dll,也就是说你反射的类的程序集dllweb层的bin下必须有
注意CreateInstance()一定是命名空间.类名,否则创建的实例为空
Assembly.Load("
程序集名")
Assembly.LoadFrom("程序集实际路径")

什么是Assembly(程序集)?
Assembly
是一个包含来程序的名称,版本号,自我描述,文件关联关系和文件位置等信息的一个集合。在.net框架中通过Assembly类来支持,该类位于System.Reflection下,物理位置位于:mscorlib.dll
Assembly
能干什么?
我们可以通过Assembly的信息来获取程序的类,实例等编程需要用到的信息。
一个简单的演示实例:
1.
建立一个Console工程名为:NamespaceRef
2.
写入如下代码:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Text;
 4 using System.Reflection;
 5
 6 namespace NamespaceRef
 7 {
 8     class Program
 9     {
10         static void Main(string[] args)
11         {
12             Country cy;
13             String assemblyName = @"NamespaceRef";
14             string strongClassName = @"NamespaceRef.China";
15             // 
注意:这里类名必须为强类名
16             // assemblyName可以通过工程的AssemblyInfo.cs中找到
17             cy = (Country)Assembly.Load(assemblyName).CreateInstance(strongClassName);
18             Console.WriteLine(cy.name);
19             Console.ReadKey();
20         }
21     }
22
23     class Country
24     {
25         public string name;
26     }
27
28     class Chinese : Country
29     {
30         public Chinese()
31         {
32             name = "你好";
33         }
34     }
35
36     class America : Country
37     {
38         public America()
39         {
40             name = "Hello";
41         }
42     }
43 }


由于Assembly的存在给我们在实现设计模式上有了一个更好的选择。
我们在开发的时候有时候会遇到这样的一个问题,根据对应的名称来创建指定的对象。如:给出chinese就要创建一个chinese对象,以前我们只能这样来写代码:

1 if (strongClassName == "China")
2     cy = new China();
3 else if (strongClassName == "America")
4     cy = new America();

那么如果我们有很长的一系列对象要创建,这样的代码维护起来是很困难的,而且也不容易阅读。现在我们可以通过在外部文件定义类的程序集名称和类的强名称来获得这样一个实例,即易于理解,又增强了扩展性还不用修改代码。
cy = (Country)Assembly.Load(assemblyName).CreateInstance(strongClassName);

  评论这张
 
阅读(1495)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017