In a previous post, Accessing app.config/web.config from T4 template, I provided an include template to provide access to the configuration file. In this post I present a stand-alone template, umm, template that you can stuff your own code into.
ConfigEnabledTemplate.tt
<#@ template inherits="Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation" language="C#v3.5" debug="true" hostSpecific="true" #>
<#@ output extension=".cs" #>
<#@ assembly name="EnvDTE" #>
<#@ assembly name="System.Configuration.dll" #>
<#@ Assembly Name="System.Core.dll" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Configuration" #>
<#@ import namespace="System.Text.RegularExpressions" #>
<#
// <copyright file="c" company="Sky Sanders">
//
// This source is a Public Domain Dedication.
//
// http://salientt4.codeplex.com
//
// Attribution is appreciated.
//
// </copyright>
/// <summary>
/// This template can serve as a starting point for a standalone template with
/// access to the hosting project and app/web configuration file.
/// </summary>
// USAGE EXAMPLES
// get a connection string
ConnectionStringSettings cs = ConnectionStrings["northwind"];
// get an appSetting value
string myAppSetting = AppSettings["myAppSetting"].Value;
// use a helper method to get value or default
string absentAppSetting = (string)AppSettingValueOrDefault("xxx","default value for absent setting");
// get a project property
string rootNamespace = Project.Properties.Item("RootNamespace").Value.ToString();
// your logic here
#>
// your boilerplate code here
namespace <#= rootNamespace #>
{
public class InlineT4ConfigAccessDemo
{
// Northwind connection string = <#= cs.ConnectionString #>
// myAppSetting = <#= myAppSetting #>
// absentAppSetting = <#= absentAppSetting #>
// rootNamespace = <#= rootNamespace #>
}
}
<#+
// Configuration Accessor Helpers
private static Configuration _config;
private static EnvDTE.Project _project;
/// <summary>
/// Example:
/// <code>
/// string cs = ConnectionStrings["myConnectionString"].ConnectionString;
/// </code>
/// </summary>
private ConnectionStringSettingsCollection ConnectionStrings
{
get { return Configuration.ConnectionStrings.ConnectionStrings;}
}
/// <summary>
/// Example:
/// <code>
/// string setting = AppSettings["mySetting"].Value;
/// </code>
/// </summary>
private KeyValueConfigurationCollection AppSettings
{
get { return Configuration.AppSettings.Settings; }
}
/// <summary>
/// Returns value of setting, if present, otherwise defaultValue
/// </summary>
/// <param name="key">appSettings key</param>
/// <param name="defaultValue">value to return if setting is absent</param>
/// <returns></returns>
private object AppSettingValueOrDefault(string key,object defaultValue)
{
if (AppSettings[key] != null)
{
return AppSettings[key].Value;
}
return defaultValue;
}
/// <summary>
/// The app/web config file for hosting project, if any
/// </summary>
private Configuration Configuration
{
get
{
if(_config==null)
{
string configurationFilename=null;
// examine each project item's filename looking for app.config or web.config
foreach (EnvDTE.ProjectItem item in Project.ProjectItems)
{
if (Regex.IsMatch(item.Name,"(app|web).config",RegexOptions.IgnoreCase))
{
// TODO: try this with linked files. is the filename pointing to the source?
configurationFilename=item.get_FileNames(0);
break;
}
}
if(!string.IsNullOrEmpty(configurationFilename))
{
// found it, map it and return it
ExeConfigurationFileMap configFile = null;
configFile = new ExeConfigurationFileMap();
configFile.ExeConfigFilename=configurationFilename;
_config = System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(configFile, ConfigurationUserLevel.None);
}
}
return _config;
}
}
/// <summary>
/// The hosting project.
/// </summary>
private EnvDTE.Project Project
{
get
{
if(_project==null)
{
// Get the instance of Visual Studio that is hosting the calling file
EnvDTE.DTE env = (EnvDTE.DTE)((IServiceProvider)this.Host).GetService(typeof(EnvDTE.DTE));
// Gets an array of currently selected projects. Since you are either in this file saving it or
// right-clicking the item in solution explorer to invoke the context menu it stands to reason
// that there is 1 ActiveSolutionProject and that it is the parent of this file....
_project = (EnvDTE.Project)((Array)env.ActiveSolutionProjects).GetValue(0);
}
return _project;
}
}
#>
Technorati tags:
T4,
CodeGen