一、预期效果
我们开发的Web应用,不但要面对开发、测试及生产环境,而且生产环境也有多个:不同的企业有不同的生产环境。不同的环境有各自的配置项,如数据库连接。
如何将开发好的Web应用,发布到各个环境中去,是一个有些麻烦的问题。目前的做法是:
- 用VS Build;
- 用压缩软件压缩,打包;
- 通过远程桌面复制到相应的环境;
- 解压,复制到IIS中;
- 修改配置项。
这样的过程,繁琐,且容易出错。我们希望能做到一键发布:
- 在VS中,右键单击项目,选择发布;
- 在弹出的对话框中选择要发布的目标,如扬子,单击发布按钮,即可完成发布。
要达到这样的效果,需要:
- 定义好解决方案配置;
- 做好配置转换;
- 配置好发布。
下面详细描述做法。
二、定义解决方案配置
VS支持为同一个Web项目定义不同的配置转换,以便发布到不同的运行环境。
例如,对于Web.Service这一项目,定义了四个不同的配置转换:
其对应关系分别是:
配置转换名称 | 含义 |
Web.Debug.config | 开发环境 |
Web.Release.config | 测试环境 |
Web.Yangzi.config | 扬子现场 |
Web.Yansan.config | 燕山现场 |
这四个配置转换文件中,包含了各个不同的运行环境的特定内容,在我们这个例子中,就是数据库连接串。对于不需要转换的内容,统一定义在Web.Config文件中。
那么,怎样创建这些转换呢?Web.Debug.config、Web.Release.config这两个转换,是在项目创建时自动生成的,其他的,则需要根据项目的需要,进行手工创建。
具体步骤包括:定义解决方案配置、创建Web配置转换。
2.1 定义解决方案配置
1、在解决方案配置的下拉列表中,选择 配置管理器:
2、在弹出的对话框中,下拉活动解决方案配置,选择 新建:
3、在弹出的对话框中,定义配置的名字:
这里给出的名称,就是第一节第3步中选择的配置名称。
由于是针对现场的生产环境,所以选择从Release配置中复制。
2.2 创建配置转换
选中Web.Config文件,右键单击,执行“添加配置转换”,就会为所创建的配置生成对应的Web配置文件。
三、进行配置转换
我们定义了解决方案配置项,但尚未为运行环境定制任何信息。仍以数据库连接串为例,看看如何为不同的运行环境配置不同的数据库连接串。
做到这一点,需要进行Web.Config转换以及Spring配置转换。
3.1 Web.Config转换
由于在执行环境中仅有Web.Config一个配置文件,而在VS中,不同运行环境中的配置项应该记录在各自的配置文件中。因此,需要经过适当的配置,使得VS在发布Web应用时,将特定运行环境的独特配置写入到Web.Config文件中。
首先,在Web.Config中定义连接串:
<configuration>
...
<connectionStrings>
<add name="em" connectionString="User ID=mes_em;Password=mes_em;Data Source=mes"/>
<add name="mm" connectionString="User ID=smes30;Password=mes2008;Data Source=mes"/>
</connectionStrings>
...
</configuration>
其次,在各配置转换文件中定义自己的项目。例如,如果扬子需要修改mm这个连接串,则可以在 Web.Yangzi.Config中定义自己的值:
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
...
<connectionStrings>
<add name="mm"
connectionString="User ID=smes30;Password=ypc_smes;Data Source=mes"
xdt:Transform="SetAttributes"
xdt:Locator="Match(name)"/>
</connectionStrings>
...
</configuration>
由于扬子mm连接串中密码和缺省值不同,需要进行单独的设置:它“重写”了<configuration>/<connectionStrings>中mm那一项的连接串,并告知VS,在匹配上name的时候,替换属性的值,也就是connectionString的值。
3.2 Spring.Net配置转换
我们现在的技术路线中,使用Spring.Net管理数据库连接。如果连接串定义在Spring.Net专用的配置文件,如Spring.Xml或Base.Xml中,而没有使用Web.Config文件中的连接串,那上面的步骤是没有意义的。实际上,我们目前的项目就是这么做的。
为此,需要对Spring配置文件进行调整,让Spring使用Web.Config中配置的字符串。
原来的Spring专用配置是:
<objects ...>
<db:provider id="DbProvider"
provider="System.Data.OracleClient"
connectionString="User ID=mes_em;Password=mes_em;Data Source=mes_em_client"/>
<db:provider id="DbProviderMes30"
provider="System.Data.OracleClient"
connectionString="User ID=smes30;Password=mes2008;Data Source=mes_em_client"/>
...
</objects>
为了让Spring使用Web.Config中的配置,需要将其调整为:
<objects ...>
<object type="Spring.Objects.Factory.Config.VariablePlaceholderConfigurer, Spring.Core">
<property name="VariableSources">
<list>
<object type="Spring.Objects.Factory.Config.ConnectionStringsVariableSource, Spring.Core" />
<object type="Spring.Objects.Factory.Config.ConfigSectionVariableSource, Spring.Core">
<property name="SectionNames" value="connectionStrings" />
</object>
</list>
</property>
</object>
<db:provider id="DbProvider"
provider="System.Data.OracleClient"
connectionString="User ID=mes_em;Password=mes_em;Data Source=mes_em_client"/>
<db:provider id="DbProviderMes30"
provider="System.Data.OracleClient"
connectionString="${mm.connectionString}" />
</objects>
与原有配置相比,发生了两点变化:
- 增加了<object type="Spring.Objects.Factory.Config.VariablePlaceholderConfigurer, Spring.Core">...</object>配置项,用于指明要从Web.Config中获取的配置内容,这里我们仅需要connecttionString;
- 原来的常量,变成了变量:${mm.connectionString},它就表示 mm对象的connectionString属性的值。
至此,所做的Web配置就可以用于发布了。
四、配置发布
最后一步是配置发布,完成了这一步,才可以在发布对话框中进行选择。为此,要做三件事情:选择名称,选择发布目的地,选择解决方案配置。
4.1 选择名称
选择一个名称,以便发布时进行选择。例如,目前的能源管理系统,可以创建的发布配置有:开发、测试、燕山,扬子等。
在VS中,右键单击要发布的项目,在快捷菜单中选择发布,在弹出的发布Web对话框中,下拉配置,选择 新建配置文件:
在弹出的对话框中,为配置文件命名:
4.2 选择目的地
对于开发、测试环境,可以使用共享目录,对于远程的,可以使用FTP、Web等连接方式。
4.3 选择解决方案配置
在设置对话框中,选择解决方案配置。
对话框中的配置,即解决方案配置,为第二步中创建的解决方案配置。
五、进一步的考虑
上面仅考虑了一次发布一个Web应用到一个企业的清醒。万一需要一次发布多个Web应用到一个企业,或者一次发布一个应用到多个企业,或者一次发布多个应用到多个企业,仅通过这样的配置,就满足不了要求了。
怎么办?只好编写脚本了。
我们发布的内容,不仅仅是Web应用,可能还要包括数据库内容更新,如数据库结构维护,数据库内容维护等。这时候要想自动发布,可以考虑编写特定的程序,放在VS中执行。