T4模板生成不同部署环境下的配置文件
使用T4模板生成不同部署环境下的配置文件
在开发企业级应用的时候,通常会有不同的开发环境,比如有开发环境,测试环境,正式环境,生产环境等。在一份代码部署到不同环境的时候,不同环境的配置文件可能需要根据目标环境不同而不同。比如在开发环境中,数据库使用的是开发环境的数据库,消息队列也使用的部署在开发机上的消息队列,传统的方式是,由发布或者配置管理员来维护这些不同环境的配置文件。通常,手工的针对不同的环境去修改配置文件容易产生错误。
有很多种不同的方式来针对不同的部署环境生成配置,最笨的方法就是可以维护几套不同的配置文件,然后在编译事件中根据编译环境变量来复制对应的配置文件;还可以使用MSBuild中的PostBuild事件脚本去修改原始的配置文件,替换其中与目标环境相关的变量或者参数;还有一些工具,比如ConfigGen,能够根据额外的环境相关配置文件,来替换原始的配置文件。这里展示如何使用T4模板来生成不同的配置文件的。
例子
T4模板是一种很流行的代码生成引擎。.NET 里面的EntityFramework似乎也是使用该引擎来生成ORM代码的。在Visual Studio能够识别和支持T4模板文件。Visual Studio有一些Addin,比如T4 Editor 能够很方便的辅助编写T4模板文件。为了演示如何根据使用T4模板生成配置文件,首先创建一个简单的控制台应用程序:
1. 打开Visual Studio创建一个控制台应用程序
2. 在默认的app.config配置文件中,添加一个数据库连接字符串,比如:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="Northwind"
connectionString="Data Source=.;Initial Catalog=Northwind;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
3. 然后添加一个新的名为App.tt的文本文件,将App.config 中的内容复制过来,然后做一些修改,如下:
<#@ template="" language="C#" #>
<#@ output="" extension= ".config" #>
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="Northwind"
connectionString="Data Source=.;Initial Catalog=Northwind;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
保存,就可以看到App.config已经在App.tt下面了,Visual Studio能够识别.tt文件,并且使用App.tt文件来生成App.config文件。App.config文件本身没有发生变化,只是现在存在与App.tt中了。注意到,这里的数据库是本地的数据库。
4. 修改App.tt,使得数据库连接字符串以参数的形式存在,如下:
<#@ template language="C#" #>
<#@ output extension= ".config" #>
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="Northwind"
connectionString="<#= this.NorthwindConnectionString #>"
providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
<#+
string NorthwindConnectionString = "Data Source=.;Initial Catalog=Northwind;Integrated Security=True";
#>
在这个版本的App.tt中,NorthwindConnectionString现在是一个模板中的私有字段了。我们给他进行初始化,并且作为模板中参数的值。
5. 现在,添加一个新的名为Dev.tt的模板文件,内容如下:
<#
this.NorthwindConnectionString = "Data Source=DEV-SERVER;Initial Catalog=Northwind;Integrated Security=True";
#>
<#@ include file="App.tt" #>
这个模板文件包含了App.tt模板文件。这个里面的字符串配置会覆盖App.tt中的字符串配置,这里可以看到,数据库连接到了名为DEV-SERVER的服务器上。当保存Dev.tt的时候,Visual Studio会自动产生Dev.Config文件,然后将其添加到Dev.tt文件中。Deve.config文件内容如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="Northwind"
connectionString="Data Source=DEV-SERVER;Initial Catalog=Northwind;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
可以看到,这个配置文件和App.config的内容很相似,只是数据库服务器变成了DEV-SERVER.
6. 在Visual Studio中,设置Dev.config文件的Copy to Output Directory属性为Copy if newer,这样Visual Studio就会将该文件拷贝到编译后的目录中。
7. 修改部署脚本,将Dev.config拷贝到开发环境,而不是默认的 app.config。部署脚本也需要根据应用程序的不同,将Dev.config重新名为目标应用程序能够识别的配置文件。比如本例中的ConsoleApplication1.exe.config
8. 重复5-7步创建针对不同部署环境的config文件。
改进
有时候,把所有的配置项都放在一个文件里面会使得整个文件看起来比较乱,所以可以对配置文件进行一些改进。 比如可以把针对数据库连接字符串的配置connectionStrings移到一个单独的文件里面,把AppSetting子项移到一个单独的文件里。
一般的配置文件,Web.config 如下,这里面appSettings里面存了RabbitMQ消息队列的配置,ConnectStrings里面存放了数据库连接字符串:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="RabbitMQHost" value="192.168.1.1"/>
<add key="RabbitMQUserName" value="admin"/>
<add key="RabbitMQUserPwd" value="11111" />
</appSettings> <connectionStrings>
<add name="Northwind"
connectionString="Data Source=DEV-SERVER;Initial Catalog=Northwind;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
一种更好的做法是,将 appSettings 和 connectionStrings 放到各自的配置文件中,Web.config如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration > <appSettings file="Config\AppSetting.config">
</appSettings> <connectionStrings configSource="Config\ConnectionString.config">
</connectionStrings> </configuration>
在项目下创建了一个名为Config的文件夹,专门用来存放子项配置。AppSetting.config内容如下:
<?xml version="1.0" encoding="utf-8" ?>
<appSettings>
<add key="RabbitMQHost" value="192.168.1.1"/>
<add key="RabbitMQUserName" value="admin"/>
<add key="RabbitMQUserPwd" value="11111" />
</appSettings>
ConnectionString.config 内容如下:
<?xml version="1.0" encoding="utf-8" ?>
<connectionStrings>
<add name="Northwind"
connectionString="Data Source=DEV-SERVER;Initial Catalog=Northwind;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
经过这样修改之后,主Web.config配置文件看起来比较简洁,这里面可以放一些与部署平台无关的配置,比如注册的一些HttpHandler之类的。而另外一些和部署平台有关的配置子项,如前面例子中的AppSetting,ConnectionString则可以做成T4模板文件,根据不同的部署环境生成对应的配置项。最后需要注意的是,在编译的时候在编译事件中,需要将子项及其所在的文件夹一并复制到发布后的目录下。这样系统才能根据相对主配置文件的路径找到子项的配置文件。
总结
本文介绍了一种使用T4模板文件,在不同环境下自动生成相应配置文件的方法,并介绍了对配置文件的改进,即把子配置项移到独立的配置文件中,然后在将子项配置文件修改为模板文件的方法,这些方法在编译和部署的时候,都需要编写相应的脚本,利用编译工具的环境变量,将对应环境的配置文件复制到编译后的目录下。这种方式教传统的同一份代码发布到不同的环境后,手动去维护和修改各个环境下的配置能够减少错误的发生和工作量。希望本文介绍的内容对大家在不同环境下生成配置文件有所借鉴和帮助。
T4模板生成不同部署环境下的配置文件的更多相关文章
- 使用T4模板生成不同部署环境下的配置文件
在开发企业级应用的时候,通常会有不同的开发环境,比如有开发环境,测试环境,正式环境,生产环境等.在一份代码部署到不同环境的时候,不同环境的配置文件可能需要根据目标环境不同而不同.比如在开发环境中,数据 ...
- MVC实用架构设计(三)——EF-Code First(3):使用T4模板生成相似代码
前言 经过前面EF的<第一篇>与<第二篇>,我们的数据层功能已经较为完善了,但有不少代码相似度较高,比如负责实体映射的 EntityConfiguration,负责仓储操作的I ...
- [转]MVC实用架构设计(三)——EF-Code First(3):使用T4模板生成相似代码
本文转自:http://www.cnblogs.com/guomingfeng/p/mvc-ef-t4.html 〇.目录 一.前言 二.工具准备 三.T4代码生成预热 (一) 单文件生成:Hello ...
- 使用T4模板生成MySql数据库实体类
注:本文系作者原创,但可随意转载. 现在呆的公司使用的数据库几乎都是MySQL.编程方式DatabaseFirst.即先写数据库设计,表设计按照规范好的文档写进EXCEL里,然后用公司的宏,生成建表脚 ...
- 【VS外接程序】利用T4模板生成模块代码
引言 记得第一次做asp.net mvc项目时,可以用model直接生成Html的增删改查页面, 没什么特殊要求都可以不用修改直接用了, 觉得很神奇,效率太高了.后来在做客户端开发时,发现很多模块都是 ...
- CSharpGL(12)用T4模板生成CSSL及其renderer代码
CSharpGL(12)用T4模板生成CSSL及其renderer代码 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码中包含10多个独立 ...
- 利用T4模板生成ASP.NET Core控制器的构造函数和参数
前言 在ASP.NET Core中引入了DI,并且通过构造函数注入参数,控制器中会大量使用DI注入各种的配置参数,如果配置注入的参数比较多,而且各个控制器需要的配置参数都基本一样的话,那么不断重复的复 ...
- Visual Studio 2013 EF5实体数据模型 EDMX 使用 T4模板生成后使用 ObjectContext对象
Visual Studio 2013 EF5实体数据模型 EDMX 使用 T4模板生成后的继承对象为DbContext,以前的熟悉的ObjectContext对象不见了,当然使用ObjectConte ...
- 热部署环境下,dubbo序列化的bug和优化
一.问题的发现与解决 (1) 在热部署下,使用dubbo的序列化一个pojo对象,反序列化时报错:ClassNotFoundException. 最后发现原因是我们的框架选择使用了java序列 ...
随机推荐
- [生产环境数据恢复]innobackupex: fatal error: OR no 'datadir' option in group 'mysqld' in MySQL options
1 运行恢复命令 [xxx@xxx-c001db1 tmp]$ time /usr/bin/innobackupex --rsync --user="user" --passwo ...
- 【原版的】PHP技术成长规划过程中猿人
PHP程序猿的技术成长规划 作者:黑夜路人(2014/10/15) 依照了解的非常多PHP/LNMP程序猿的发展轨迹.结合个人经验体会,抽象出非常多程序猿对未来的迷漫,特别对技术学习的盲目和慌乱.简单 ...
- [原创].NET 业务框架开发实战之六 DAL的重构
原文:[原创].NET 业务框架开发实战之六 DAL的重构 .NET 业务框架开发实战之六 DAL的重构 前言:其实这个系列还是之前的".NET 分布式架构开发实战 ",之所以改了 ...
- 付款页面DEMO
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveHRxdWVlbg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA ...
- 查询系统--基于Solr4.9.0实现
为什么非要搜索系统 随着在产品的数量的增长.和复杂的检索要求,直接从数据库中检索信息,它已经无法满足展示机搜索需求. 实例: keyword=%E8%8B%B9%E6%9E%9C&enc=ut ...
- 【转】JAVA 网络编程
网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习. 在 学习网络编程以前,很多初学者可能觉得网络编 ...
- 左右 Java 于 finally 深度分析语句块
首先,让我们来问你一个问题:finally 声明块将运行? 很多人认为 finally 语句块是一定要运行.其中还包括了一些非常有经验的 Java 程序猿.不幸的是,没有像很多像人们想象,对于这个问题 ...
- Cocos观察者设计模式和通报机制
观察员(Observer)模式也称为公告/订阅(Publish/Subscribe)模式.这是 MVC( 模型-视图-控制器)模型的重要组成部分.天气一直讨论的英国最喜欢的话题,近期天气变化几年已成为 ...
- Zero Downtime Upgrade of Oracle 10g to Oracle 11g Using GoldenGate — 3
DDL Setup Steps SQL> grant execute on utl_file to ggs; Grant succeeded. Create GLOBALS file [orac ...
- js控制文本框仅仅能输入中文、英文、数字与指定特殊符号
JS 控制文本框仅仅能输入数字 <input onkeyup="value=value.replace(/[^0-9]/g,'')"onpaste="value=v ...