Friday, November 12, 2010

build and depoly referenced library in special path rather than application path for .Net application

 
如何将依赖的.Net library放在一个专门的目录?

一般情况下, .Net程序的library需要部署在GAC或者exe的目录下, GAC部署不是一种xcopy方式, 我几乎不用, 多数是直接将lib放在应用程序的目录下.

有没有办法将这些lib放到一个特定的目录呢? 其实.Net有多种机制, 可以实现这样的要求. 下面介绍一种最实用而且是最常用的lib部署机制, 在应用程序exe的config文件中, 增加privatePath设置, 告诉应用程序在哪些目录下查找依赖的lib. 对于web应用, 设置privatePath应该在web.config中.

让我们看看下面2个场景, 该如何编译和部署程序.
 场景1, 我们有app1.exe, 它引用了core1.dll, 在core1.dll中引用了oracle.dll和mysql.dll, 我想把oracle.dll和mysql.dll分别部署在 db_provider/oracle和db_provider/mysql中. 而core1.dll和app1.exe仍然在同一个目录下.
 场景2, 我们有app2.exe, 它直接引用了引用了oracle.dll和mysql.dll. 我想把oracle.dll和mysql.dll分别部署在 db_provider/oracle和db_provider/mysql中.

其实, 这2个场景的处理方式完全一样.

如何编译?
1. 在app1.exe(场景1)和app2.exe(场景2)的项目中增加app.config文件, 在其中增加下面的privatePath.见本文最后部分的代码
2. 和正常项目完全一样, 直接在app1和app2项目中引用所依赖的lib
3. 用VS编译app1和app2项目

如何部署?
VS编译输出的lib都放在了app1.exe和app2.exe目录下了, 你需要手动创建目录db_provider/oracle和db_provider/mysql, 并将oracle.dll和mysql.dll移过去. 当然, 最好是将这个步骤做成bat文件, 甚至将bat放在VS的build事件中, 这样在每次build后, 都自动完成文件整理工作.


下面是应用程序的app.config的内容:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
 <runtime>
   <assemblyBinding
      xmlns="urn:schemas-microsoft-com:asm.v1">
     <probing privatePath="db_provider/oracle;db_provider/mysql"/>
   </assemblyBinding>
 </runtime>
</configuration>