当前位置:编程学习 > C#/ASP.NET >>

Assembly学习心得(2)

答案:     第二部分(例子)
  
   下面是一个完整的例子来逐一说明上面所提到的概念,以加深理解。
   整个例子包含7个文件(在主目录下):
   主目录为 …/Assembly ----源程序目录
   …/Assembly/Bin ---- 编译结果输出的目录,也就是应用程序主目
  
   录。
  
  
  
   文件名
   类型
   说明
  
   App.cs
   Code源文件
   主程序,包含程序入口,
   属于namespace1
  
   ClassA.cs
   Code源文件
   类型A,包含一个静态方法,
   属于namespace1
  
   ClassB.cs
   Code源文件
   类型B,包含一个静态方法,
   属于namespace2
  
   AssemblyInfo.cs
   Code源文件
   包含程序集签名信息,
   版本信息等
  
   App.Key
   公钥/私钥对文件
   用来给程序集签名,
   生成强命名程序集
  
   App.PublicKey
   只包含共有密钥
   只储存共有密钥,
   用SN.exe来查看
  
   App.exe.config
   Xml格式配置文件
   App.exe的应用程序配置文件
  
   源代码
   App.cs
   namespace namespaceA {
   public class App {
   static void Main (string[] args) {
   System.Console.WriteLine(ClassA.ShowMe());
   System.Console.WriteLine(namespaceB.ClassB.ShowMe());
   }
   }
   }
   ClassA.cs
   namespace namespaceA {
   public class ClassA {
   public static string ShowMe()
   {
   return "This is ClassA";
   }
   }
   }
  
   ClassB.cs
   namespace namespaceB {
   public class ClassB {
   public static string ShowMe() {
   return "This is ClassB";
   }
   }
   }
   AssemblyInfo.cs
   ////////////////////////////////////////////////////////////////////////////////
   // Module: AssemblyInfo.cs
   ////////////////////////////////////////////////////////////////////////////////
   using System.Reflection;
   ////////////////////////////////////////////////////////////////////////////////
   // Set CompanyName, LegalCopyright, and LegalTrademarks
   [assembly: AssemblyCompany("App Company")]
   [assembly: AssemblyCopyright("Copyright (C) 2004 @ App Company")]
   [assembly: AssemblyTrademark("App is a test only program")]
   ////////////////////////////////////////////////////////////////////////////////
   // Set ProductName and ProductVersion
   [assembly: AssemblyProduct("App Product")]
   [assembly: AssemblyInformationalVersion("1.0.0.0")]
   ////////////////////////////////////////////////////////////////////////////////
   // Set FileVersion and AssemblyVersion
  
   [assembly: AssemblyFileVersion("1.0.0.0")]
   [assembly: AssemblyVersion("1.0.0.0")]
   [assembly: AssemblyTitle("App type assembly")]
   [assembly: AssemblyDescription("App Aassembly is a test only assembly")]
  
   ////////////////////////////////////////////////////////////////////////////////
   // Set Culture
   [assembly: AssemblyCulture("")]
   [assembly: AssemblyDelaySign(false)]
   [assembly: AssemblyKeyFile("App.key")]
   [assembly: AssemblyKeyName("")]
   App.key和App.PublicKey是二进制格式存储的,不能直接查看。后面例子中会用到
  
   1. 把源代码编译为托管模块(Managed Module)
   csc /out:bin/classA.module /t:module classA.cs
   参数:
   /out: 输出路径
   /t: 输出格式。可以有四种,分别是:
   library ---- DLL程序集
   exe ---- 控制台可执行程序(也是程序集的一种)
   winexe ---- Windows可执行程序(同样也是程序集的一种)
   module ---- 托管模块(程序集的一部分)
  
   说明: 托管模块的的扩展名可以是任意的(也可以没有),因为编译的时候都是以元数据的格式读取的。
  
   2. 把源代码编译为程序集(Assembly)
   l 把ClassB编译为一个单文件程序集
   csc /out:bin/classB.dll /t:library classB.cs
   l 把App.cs,ClassA.module和ClassB.dll编译为一个多文件程序集
   csc /out:bin/App.exe /t:exe app.cs /addmodule:bin/classA.module /r:bin/classB.dll
   参数:
   /addmodule: 把托管模块添加到程序集中 /r: 添加引用说明: 上面生成的程序集因为没有经过公钥/私有签名,所以生成的是非强命名类型的程序集。 生成的程序集App.exe的清单中只包含对classA.module托管模块的说明,并不 包classA.module的元数据,所以App.exe和classA.moudle必须在同一目录中。App.exe在运行时,如果用到对classA.module中类型的引用,则会去classA.moudel文件进行查找,如果classA.moude文件不存在,则会引发System.IO.FileNotFoundException。如果App.exe不会用到class.module中的类型,则classA.module存不存在都不会对App.exe的执行产生任何影响(这就是上面提到的Assembly的好处之一,Assembly只是一个逻辑上的组合)。
   App.exe还用到了对ClassB.dll的引用,因为classB.dll不是一个强命名类型,所以它只能进行私有部署,可以和App.exe放在一起,也可以放在主目录下的其他子目录下。(后面通过应用程序更改配置文件,可以重定向指classB.dll的引用)。
  
   3. 更改应用程序配置文件(App.exe.config),重定向对classB.dll的引用。
  
   现在App.exe,classA.moudle和classB.dll都在Bin目录下,app.exe在运行时会找到所有它需要的类型,所以运行正常。
  
   如果把在Bin目录下新建一个目录,比如sub,并把classB.dll移动到sub目录下,再运行App.exe就会出错。同样会引发System.IO.FileNotFoundException错误,因为App.exe运行时需要的classB类型找不到。这时候就需要更改添加(如果没有)或更改应用程序配置文件,应用程序配置文件是一个xml格式的配置文件,和web.config文件的作用差不多,是配置应用程序运行时的行为的。
  
   注意:配置文件的名字必须是应用程序名字再加一个.config,且必须在同一目录下
   详细信息参考: ms-help://MS.MSDNQTR.2004APR.1033/cpguide/html/
   cpconnetapplicationconfigurationscenarios.htm
  
   App.exe.config文件的内容:
   <?xmlversion="1.0"encoding="utf-8"?>
   <configuration>
   <runtime>
   <assemblyBindingxmlns="urn:schemas-microsoft-com:asm.v1">
   <probingprivatePath="sub"/>
   </assemblyBinding>
   </runtime>
   </configuration> 当App.exe运行时,它就会在主目录下的sub目录中找到classB.dll,然后继续行。
   说明:
   当CLR需要定位一个程序集时,它将扫描应用程序的几个子目录,下面是才CLR扫描一个程序集时的顺序:
   …/Assembly/Bin/classB.DLL.
   …/Assembly/Bin/classB/classB.DLL.
   …/Assembly/Bin/sub/classB.DLL.
   …/Assembly/Bin/sub/cl

上一个:通过禁止使用xp_cmdShell提高安全
下一个:Assembly学习心得(1)

CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,