Tim Van Wassenhove

Passionate geek, interested in Technology. Proud father of two

12 Feb 2010

Clever TemplateFile hack

In my current project i use TemplateFileTask (MSBuild Community Tasks Project) to generate configuration files. I ran into the problem that i don’t want to expose a MEX endpoint in production. This is my initial template file

<service behaviorconfiguration="DemoBehavior" name="DemoService.FileService">
	<endpoint address="" binding="ws2007HttpBinding" contract="DemoService.IFileService" />
	${MexEndpoint}
</service>

And here is my initial msbuild task

<Project ToolsVersion="3.5" dDfaultTargets="GenerateConfigFiles" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
	<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
	<Target Name="GenerateConfigFiles">
		<PropertyGroup>
			<MexEndpoint>
				<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
			</MexEndpoint>
		</PropertyGroup>

		<PropertyGroup Condition=" '$(Env)'=='Production' ">
			<MexEndpoint></MexEndpoint>
		</PropertyGroup>

		<ItemGroup>
			<Tokens Include="MexEndpoint">
				<ReplacementValue>$(MexEndpoint)</ReplacementValue>
			</Tokens>
		</ItemGroup>

		<TemplateFile Template="Web.template.config" OutputFileName="Web.config" Tokens="@(Tokens)" />
	</Target>
</Project>

This results in the following configuration file: (WCF does not like the xml namespace declaration):

<service behaviorconfiguration="DemoBehavior" name="DemoService.FileService">
	<endpoint address="" binding="ws2007HttpBinding" contract="DemoService.IFileService" />
	<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
</service>

I noticed that a smart collegue of mine came up with the following template file:

<service behaviorconfiguration="DemoBehavior" name="DemoService.FileService">
	<endpoint address="" binding="ws2007HttpBinding" contract="DemoService.IFileService" />
	<${MexBegin}endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /${MexEnd}>
</service>

And this is how he defines the MexBegin and MexEnd properties in msbuild:

<PropertyGroup>
	<MexBegin></MexBegin>
	<MexEnd></MexEnd>
</PropertyGroup>

<PropertyGroup Condition=" '$(Env)'=='Production' ">
	<MexBegin>!--</MexBegin>
	<MexEnd>--</MexEnd>
</PropertyGroup>

This leads to a nice MEX endpoint for all environments and in Production we get the following:

<!--endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /-->

Perhaps it is cleaner to implement my own TemplateFileTask but untill then this clever hack does the job.