<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>A Technical Perspective</title>
	<atom:link href="http://maximelabelle.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://maximelabelle.wordpress.com</link>
	<description>Un site utilisant WordPress.com</description>
	<lastBuildDate>Wed, 08 Feb 2012 21:22:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='maximelabelle.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>A Technical Perspective</title>
		<link>http://maximelabelle.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://maximelabelle.wordpress.com/osd.xml" title="A Technical Perspective" />
	<atom:link rel='hub' href='http://maximelabelle.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Session TechDays &#8211; 2012 : Mettre en Oeuvre une Plateforme d&#8217;Intégration et de Gestion des Informations de l&#8217;Entreprise (EIM) avec SQL Server 2012 Master Data Services</title>
		<link>http://maximelabelle.wordpress.com/2012/02/08/session-techdays-2012-mettre-en-oeuvre-une-plateforme-dintegration-et-de-gestion-des-informations-de-lentreprise-eim-avec-sql-server-2012-master-data-services/</link>
		<comments>http://maximelabelle.wordpress.com/2012/02/08/session-techdays-2012-mettre-en-oeuvre-une-plateforme-dintegration-et-de-gestion-des-informations-de-lentreprise-eim-avec-sql-server-2012-master-data-services/#comments</comments>
		<pubDate>Wed, 08 Feb 2012 15:22:15 +0000</pubDate>
		<dc:creator>Maxime Labelle</dc:creator>
				<category><![CDATA[Master Data Services]]></category>

		<guid isPermaLink="false">http://maximelabelle.wordpress.com/?p=389</guid>
		<description><![CDATA[Warning: this post is about my contribution to the Microsoft TechDays 2011 in Paris and is therefore written in french. Pour la deuxième année consécutive, j&#8217;ai le plaisir d&#8217;animer une session sur la dernière version de SQL Server 2012 Master &#8230; <a href="http://maximelabelle.wordpress.com/2012/02/08/session-techdays-2012-mettre-en-oeuvre-une-plateforme-dintegration-et-de-gestion-des-informations-de-lentreprise-eim-avec-sql-server-2012-master-data-services/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&amp;blog=16599311&amp;post=389&amp;subd=maximelabelle&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><em>Warning: this post is about my contribution to the Microsoft TechDays 2011 in Paris and is therefore written in french.</em></p>
<p>Pour <a href="http://maximelabelle.wordpress.com/2011/03/16/session-techdays-2011-les-technologies-dintegration-de-mdm-et-de-soa/">la deuxième année consécutive</a>, j&#8217;ai le plaisir <a href="http://www.microsoft.com/france/mstechdays/programmes/parcours.aspx#DomID=3b327402-34a7-4f9e-9704-9ddebed8094f&amp;SessionID=e1a5bb87-7ce9-47b5-b2dd-c8dec94b87ae">d&#8217;animer une session</a> sur la dernière version de <a href="http://msdn.microsoft.com/en-us/sqlserver/ff943581">SQL Server 2012 Master Data Services</a> à l&#8217;occasion du salon Microsoft TechDays 2012, qui se tient au Palais des Congrès à Paris.</p>
<p>
Cette année, je me suis vu confier l&#8217;animation de la session par Damien Cudel. Je me suis associé à Laurent Banon et mon collègue Radoine pour porter cette session sur un produit en lequel nous croyons vraiment en 2012 !</p>
<p>
Le sujet, ambitieux, de la session est le suivant:</p>
<p>
Avec SQL Server 2012 Master Data Services, la plateforme Application Server de Microsoft se dote d&#8217;un outil puissant de gestion de la donnée de référence. Nous allons montrer en quoi et comment cette solution, qui dispose d&#8217;une fonctionnalité de maintien de la qualité de la donnée, complète l&#8217;écosystème applicatif et permet de mettre en oeuvre des processus d&#8217;intégration, d&#8217;enrichissement et de diffusion des données de référence, en temps réel, entre les différentes partenaires applicatifs du système d&#8217;information, à l&#8217;intérieur comme à l&#8217;extérieur de l&#8217;entreprise.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maximelabelle.wordpress.com/389/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maximelabelle.wordpress.com/389/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maximelabelle.wordpress.com/389/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maximelabelle.wordpress.com/389/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maximelabelle.wordpress.com/389/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maximelabelle.wordpress.com/389/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maximelabelle.wordpress.com/389/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maximelabelle.wordpress.com/389/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maximelabelle.wordpress.com/389/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maximelabelle.wordpress.com/389/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maximelabelle.wordpress.com/389/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maximelabelle.wordpress.com/389/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maximelabelle.wordpress.com/389/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maximelabelle.wordpress.com/389/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&amp;blog=16599311&amp;post=389&amp;subd=maximelabelle&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maximelabelle.wordpress.com/2012/02/08/session-techdays-2012-mettre-en-oeuvre-une-plateforme-dintegration-et-de-gestion-des-informations-de-lentreprise-eim-avec-sql-server-2012-master-data-services/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4c7bbc359fc392f6afd584cf99a5b427?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maximelabelle</media:title>
		</media:content>
	</item>
		<item>
		<title>PowerShell Provider for BizTalk Server 1.2.0.4 Released</title>
		<link>http://maximelabelle.wordpress.com/2012/02/08/powershell-provider-for-biztalk-server-1-2-0-4-released/</link>
		<comments>http://maximelabelle.wordpress.com/2012/02/08/powershell-provider-for-biztalk-server-1-2-0-4-released/#comments</comments>
		<pubDate>Wed, 08 Feb 2012 15:12:52 +0000</pubDate>
		<dc:creator>Maxime Labelle</dc:creator>
				<category><![CDATA[BizTalk]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://maximelabelle.wordpress.com/?p=386</guid>
		<description><![CDATA[It&#8217;s been a long while since I did some blogging. Fortunately, Randal has been working towards producing a new 1.2.0.4 release of our PowerShell provider for BizTalk Server. This version fixes a couple bugs and I invite everyone to test &#8230; <a href="http://maximelabelle.wordpress.com/2012/02/08/powershell-provider-for-biztalk-server-1-2-0-4-released/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&amp;blog=16599311&amp;post=386&amp;subd=maximelabelle&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a long while since I did some blogging.</p>
<p>Fortunately, <a href="http://biztalkmessages.vansplunteren.net/">Randal</a> has been working towards producing a new <a href="http://psbiztalk.codeplex.com/releases/view/81225#DownloadId=334945">1.2.0.4 release</a> of our <a href="http://psbiztalk.codeplex.com">PowerShell provider for BizTalk Server</a>.</p>
<p>This version fixes a couple bugs and I invite everyone to test it out.</p>
<p>Thanks, Randal!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maximelabelle.wordpress.com/386/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maximelabelle.wordpress.com/386/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maximelabelle.wordpress.com/386/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maximelabelle.wordpress.com/386/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maximelabelle.wordpress.com/386/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maximelabelle.wordpress.com/386/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maximelabelle.wordpress.com/386/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maximelabelle.wordpress.com/386/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maximelabelle.wordpress.com/386/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maximelabelle.wordpress.com/386/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maximelabelle.wordpress.com/386/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maximelabelle.wordpress.com/386/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maximelabelle.wordpress.com/386/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maximelabelle.wordpress.com/386/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&amp;blog=16599311&amp;post=386&amp;subd=maximelabelle&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maximelabelle.wordpress.com/2012/02/08/powershell-provider-for-biztalk-server-1-2-0-4-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4c7bbc359fc392f6afd584cf99a5b427?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maximelabelle</media:title>
		</media:content>
	</item>
		<item>
		<title>Microsoft® MVP BizTalk 2012</title>
		<link>http://maximelabelle.wordpress.com/2012/01/02/microsoft-mvp-biztalk-2011/</link>
		<comments>http://maximelabelle.wordpress.com/2012/01/02/microsoft-mvp-biztalk-2011/#comments</comments>
		<pubDate>Mon, 02 Jan 2012 06:50:03 +0000</pubDate>
		<dc:creator>Maxime Labelle</dc:creator>
				<category><![CDATA[BizTalk]]></category>

		<guid isPermaLink="false">https://maximelabelle.wordpress.com/?p=380</guid>
		<description><![CDATA[It is with great honor and much pride that I have been given the Microsoft Most Valuable Professional award for Microsoft BizTalk Server in 2012, for the second year in a row. A big thanks to all my family, my &#8230; <a href="http://maximelabelle.wordpress.com/2012/01/02/microsoft-mvp-biztalk-2011/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&amp;blog=16599311&amp;post=380&amp;subd=maximelabelle&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>
It is with great honor and much pride that I have been given the Microsoft Most Valuable Professional award for Microsoft BizTalk Server in 2012, for the second year in a row.</p>
<p style="text-align:center;">
<img src="http://maximelabelle.files.wordpress.com/2011/01/mvp_logo.png?w=640"></p>
<p>
A big thanks to all my family, my friends and colleagues that supported me throughout the year.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maximelabelle.wordpress.com/380/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maximelabelle.wordpress.com/380/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maximelabelle.wordpress.com/380/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maximelabelle.wordpress.com/380/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maximelabelle.wordpress.com/380/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maximelabelle.wordpress.com/380/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maximelabelle.wordpress.com/380/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maximelabelle.wordpress.com/380/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maximelabelle.wordpress.com/380/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maximelabelle.wordpress.com/380/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maximelabelle.wordpress.com/380/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maximelabelle.wordpress.com/380/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maximelabelle.wordpress.com/380/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maximelabelle.wordpress.com/380/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&amp;blog=16599311&amp;post=380&amp;subd=maximelabelle&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maximelabelle.wordpress.com/2012/01/02/microsoft-mvp-biztalk-2011/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4c7bbc359fc392f6afd584cf99a5b427?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maximelabelle</media:title>
		</media:content>

		<media:content url="http://maximelabelle.files.wordpress.com/2011/01/mvp_logo.png" medium="image" />
	</item>
		<item>
		<title>Building Multiple Projects in Order with MSBuild</title>
		<link>http://maximelabelle.wordpress.com/2011/11/29/building-multiple-projects-in-order-with-msbuild/</link>
		<comments>http://maximelabelle.wordpress.com/2011/11/29/building-multiple-projects-in-order-with-msbuild/#comments</comments>
		<pubDate>Tue, 29 Nov 2011 20:58:36 +0000</pubDate>
		<dc:creator>Maxime Labelle</dc:creator>
				<category><![CDATA[BizTalk]]></category>
		<category><![CDATA[MSBuild]]></category>

		<guid isPermaLink="false">http://maximelabelle.wordpress.com/?p=355</guid>
		<description><![CDATA[When building projects grouped in a solution, Visual Studio figures out the project dependencies and respect the build order. However, if you&#8217;re not using Visual Studio .sln solution files when building a set of projects with MSBuild, the build order &#8230; <a href="http://maximelabelle.wordpress.com/2011/11/29/building-multiple-projects-in-order-with-msbuild/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&amp;blog=16599311&amp;post=355&amp;subd=maximelabelle&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>When building projects grouped in a solution, Visual Studio figures out the project dependencies and respect the build order. However, if you&#8217;re not using Visual Studio .sln solution files when building a set of projects with MSBuild, the build order is left to the author of the MSBuild script.</p>
<p>I&#8217;m creating a custom Build system, in order to convert complete BizTalk solutions from source code, to Windows Installer .msi scripts. This involves not only building the projects (compiling), but also putting relevant managed assemblies to the Global Assembly Cache, deploying assemblies and third-party references to a BizTalk Application, applying bindings and exporting the resulting BizTalk application to a .msi file&#8230; I choose not to use the well-known and excellent <a href="http://biztalkdeployment.codeplex.com/">BizTalk Deployment Framework</a>, because, I&#8217;m primarily interested in a <em>build</em> system, tailored to a local development box in order to boost productivity.</p>
<p>In our shop, deployment is handled with a custom PowerShell-based solution that makes extensive use of the <a href="http://psbiztalk.codeplex.com/">PowerShell provider for BizTalk</a>. But for local development, there definitely was a need for improving productivity. For instance, by enabling <a href="http://maximelabelle.wordpress.com/2011/10/26/enabling-incremental-compilation-of-biztalk-btproj-msbuild-files/">incremental build support</a> for BizTalk Server 2010 .btproj project files, we were able to dramatically cut the build times.</p>
<p>One of the things that broke when using our custom build system was to be able to perform the opposite operations &#8211; that is, undeploy &#8211; the BizTalk Application. This involves figuring out the correct chain of dependencies betweeen assemblies and remove then in the appropriate order from BizTalk.</p>
<p>Fortunately, MSBuild is extensible and it is not really difficult to include such features to your build scripts.</p>
<p>In order to alter you build system to include dependency-checking and correct build (and reverse cleanup) order, you need to apply the solution in two stages:</p>
<ul>
<li>First, you need to gather project dependencies</li>
<li>Second, you need to figure out the correct build order</li>
</ul>
<p><span style="font-family:Tahoma;font-weight:bold;">Gathering Project Dependencies</span></p>
<p>Figuring project dependencies relies on the use of &#8216;Project References&#8217; in order to express project dependencies. This is what uses Visual Studio when building the projects from the solution. In order to gather the depencencies betweeen several projects, Visual Studio uses the <span style="font-family:'Courier New';">ResolveProjectReferences</span> builtin MSBuild task.</p>
<pre style="border:#cecece 1px solid;background-color:#fbfbfb;width:100%;font-family:consolas, 'Courier New', courier, monospace;font-size:12px;margin:0;padding:5px 1em;"><span style="color:blue;">&lt;</span><span style="color:maroon;">Target</span> <span style="color:red;">Name</span>=<span style="color:blue;">"_ComputeProjectReference"</span> <span style="color:red;">Inputs</span>=<span style="color:blue;">"%(Project.Identity)"</span> <span style="color:red;">Outputs</span>=<span style="color:blue;">"%(Project.Identity)__force_output__"</span><span style="color:blue;">&gt;</span>
  <span style="color:blue;">&lt;</span><span style="color:maroon;">MSBuild</span> <span style="color:red;">Projects</span>=<span style="color:blue;">"@(Project)"</span> <span style="color:red;">Targets</span>=<span style="color:blue;">"ResolveProjectReferences"</span><span style="color:blue;">&gt;</span>
    <span style="color:blue;">&lt;</span><span style="color:maroon;">Output</span> <span style="color:red;">TaskParameter</span>=<span style="color:blue;">"TargetOutputs"</span> <span style="color:red;">ItemName</span>=<span style="color:blue;">"ResolvedProjectReferences"</span> /<span style="color:blue;">&gt;</span>
  <span style="color:blue;">&lt;</span>/<span style="color:maroon;">MSBuild</span><span style="color:blue;">&gt;</span>

  <span style="color:blue;">&lt;</span><span style="color:maroon;">ItemGroup</span><span style="color:blue;">&gt;</span>
    <span style="color:blue;">&lt;</span><span style="color:maroon;">ProjectReferenceItemSpec</span> <span style="color:red;">Include</span>=<span style="color:blue;">"%(ResolvedProjectReferences.OriginalProjectReferenceItemSpec)"</span> /<span style="color:blue;">&gt;</span>
  <span style="color:blue;">&lt;</span>/<span style="color:maroon;">ItemGroup</span><span style="color:blue;">&gt;</span>

 <span style="color:blue;">&lt;</span><span style="color:maroon;">ItemGroup</span><span style="color:blue;">&gt;</span>
    <span style="color:blue;">&lt;</span><span style="color:maroon;">ProjectReference</span> <span style="color:red;">Include</span>=<span style="color:blue;">"@(Project)"</span><span style="color:blue;">&gt;</span>
      <span style="color:blue;">&lt;</span><span style="color:maroon;">ProjectReference</span><span style="color:blue;">&gt;</span>@(ProjectReferenceItemSpec)<span style="color:blue;">&lt;</span>/<span style="color:maroon;">ProjectReference</span><span style="color:blue;">&gt;</span>
    <span style="color:blue;">&lt;</span>/<span style="color:maroon;">ProjectReference</span><span style="color:blue;">&gt;</span> <span style="color:blue;">&lt;</span>/<span style="color:maroon;">ItemGroup</span><span style="color:blue;">&gt;</span>
<span style="color:blue;">&lt;</span>/<span style="color:maroon;">Target</span><span style="color:blue;">&gt;</span></pre>
<p><span style="font-weight:bold;">Hint:</span> scanning project dependencies actually triggers a build and takes time. This can sometimes be undesirable. In order to speed things up a litte and avoid redundant builds, you can persist the project dependencies in a temporary file, with the <span style="font-family:'Courier New';">WriteLinesToFile</span> MSBuild task, and read the cached information on subsequent builds with the <span style="font-family:'Courier New';">ReadLinesFromFile</span> task.</p>
<p><span style="font-family:Tahoma;font-weight:bold;">Figuring out the Correct Build Order</span></p>
<p>When all project references have been gathered, figuring out the correct build order is trivial. In fact, this subject has been beaten to death already, and is an application of Graph Theory. More specifically, project dependencies form a <a href="http://en.wikipedia.org/wiki/Directed_acyclic_graph">Directed Acyclic Graph</a>. The action of ordering the projects for successful build is called a <a href="http://en.wikipedia.org/wiki/Topological_sorting">Topological Sort</a>.</p>
<p>The following simple custom class includes a direct translation of the corresponding Wikipedia entry on the subject:</p>
<pre style="border:#cecece 1px solid;background-color:#fbfbfb;width:100%;font-family:consolas, 'Courier New', courier, monospace;font-size:12px;margin:0;padding:5px 1em;"><span style="color:blue;">using</span> System;
<span style="color:blue;">using</span> System.Collections.Generic;

<span style="color:blue;">namespace</span> System.Collections.Generic
{
    <span style="color:blue;">public</span> <span style="color:blue;">class</span> Graph&lt;T&gt;
    {
        <span style="color:blue;">#region</span><span style="color:gray;"> Constructors</span>

        <span style="color:blue;">private</span> <span style="color:lightseagreen;">IList</span>&lt;T&gt; nodes_ = <span style="color:blue;">new</span> <span style="color:lightseagreen;">List</span>&lt;T&gt;();
        <span style="color:blue;">private</span> <span style="color:lightseagreen;">IDictionary</span>&lt;<span style="color:lightseagreen;">Int32</span>, <span style="color:lightseagreen;">List</span>&lt;<span style="color:lightseagreen;">Int32</span>&gt;&gt; edges_ = <span style="color:blue;">new</span> <span style="color:lightseagreen;">Dictionary</span>&lt;<span style="color:lightseagreen;">Int32</span>, <span style="color:lightseagreen;">List</span>&lt;<span style="color:lightseagreen;">Int32</span>&gt;&gt;();

        <span style="color:blue;">#endregion</span>

        <span style="color:blue;">#region</span><span style="color:gray;"> Operations</span>

        <span style="color:blue;">public</span> <span style="color:blue;">void</span> AddEdge(T item, T dependency)
        {
            <span style="color:blue;">int</span> index_item = AddNode(item);
            <span style="color:blue;">int</span> index_dependency = AddNode(dependency);

            edges_[index_item].Add(index_dependency);
        }

        <span style="color:blue;">public</span> <span style="color:lightseagreen;">Int32</span> AddNode(T item)
        {
            <span style="color:blue;">if</span> (!nodes_.Contains(item))
                nodes_.Add(item);

            <span style="color:blue;">int</span> index = IndexOf(item);

            <span style="color:blue;">if</span> (!edges_.ContainsKey(index))
                edges_.Add(index, <span style="color:blue;">new</span> <span style="color:lightseagreen;">List</span>&lt;<span style="color:lightseagreen;">Int32</span>&gt;());

            <span style="color:blue;">return</span> index;
        }

        <span style="color:blue;">public</span> T[] Sort()
        {
            <span style="color:lightseagreen;">IList</span>&lt;T&gt; Nodes = <span style="color:blue;">new</span> <span style="color:lightseagreen;">List</span>&lt;T&gt;(nodes_);
            <span style="color:lightseagreen;">IDictionary</span>&lt;<span style="color:lightseagreen;">Int32</span>, <span style="color:lightseagreen;">List</span>&lt;<span style="color:lightseagreen;">Int32</span>&gt;&gt; Edges = <span style="color:blue;">new</span> <span style="color:lightseagreen;">Dictionary</span>&lt;<span style="color:lightseagreen;">Int32</span>, <span style="color:lightseagreen;">List</span>&lt;<span style="color:lightseagreen;">Int32</span>&gt;&gt;(edges_);

            <span style="color:green;">// L ← Empty list that will contain the sorted elements</span>
            <span style="color:green;">// S ← Set of all nodes with no incoming edges</span>

            <span style="color:lightseagreen;">List</span>&lt;T&gt; L = <span style="color:blue;">new</span> <span style="color:lightseagreen;">List</span>&lt;T&gt;(Nodes.Count);
            <span style="color:lightseagreen;">List</span>&lt;<span style="color:lightseagreen;">Int32</span>&gt; S = <span style="color:blue;">new</span> <span style="color:lightseagreen;">List</span>&lt;<span style="color:blue;">int</span>&gt;(Nodes.Count);
            <span style="color:blue;">foreach</span> (<span style="color:lightseagreen;">Int32</span> index <span style="color:blue;">in</span> Edges.Keys)
                <span style="color:blue;">if</span> (Edges[index].Count == 0)
                    S.Add(index);

            <span style="color:green;">// while S is non-empty do</span>
            <span style="color:green;">// remove a node n from S</span>
            <span style="color:green;">// insert n into L</span>
            <span style="color:green;">// for each node m with an edge e from n to m do</span>
            <span style="color:green;">// remove edge e from the graph</span>
            <span style="color:green;">// if m has no other incoming edges then</span>
            <span style="color:green;">// insert m into S</span>

            <span style="color:blue;">while</span> (S.Count != 0)
            {
                T node = Nodes[S[0]];
                S.RemoveAt(0);

                L.Add(node);

                <span style="color:lightseagreen;">Int32</span> index_from = Nodes.IndexOf(node);

                <span style="color:blue;">foreach</span> (KeyValuePair&lt;<span style="color:lightseagreen;">Int32</span>, <span style="color:lightseagreen;">List</span>&lt;<span style="color:lightseagreen;">Int32</span>&gt;&gt; item <span style="color:blue;">in</span> Edges)
                {
                    <span style="color:blue;">if</span> (item.Value.Contains(index_from))
                    {
                        item.Value.Remove(index_from);
                        <span style="color:blue;">if</span> (item.Value.Count == 0)
                            S.Add(item.Key);
                    }
                }
            }

            <span style="color:green;">// if graph has edges then</span>
            <span style="color:green;">// output error message (graph has at least one cycle)</span>
            <span style="color:green;">// else </span>
            <span style="color:green;">// output message (proposed topologically sorted order: L)</span>

            <span style="color:blue;">foreach</span> (<span style="color:lightseagreen;">List</span>&lt;<span style="color:lightseagreen;">Int32</span>&gt; item <span style="color:blue;">in</span> Edges.Values)
                <span style="color:blue;">if</span> (item.Count != 0)
                    <span style="color:blue;">throw</span> <span style="color:blue;">new</span> ApplicationException(<span style="color:maroon;">"Circular dependency detected!"</span>);

            <span style="color:blue;">return</span> L.ToArray();
        }

        <span style="color:blue;">public</span> T[] Sort(<span style="color:blue;">bool</span> reverse)
        {
            T[] array = Sort();
            <span style="color:blue;">if</span> (reverse)
                <span style="color:lightseagreen;">Array</span>.Reverse(array);
            <span style="color:blue;">return</span> array;
        }

        <span style="color:blue;">#endregion</span>

        <span style="color:blue;">#region</span><span style="color:gray;"> Implementation</span>

        <span style="color:blue;">private</span> <span style="color:lightseagreen;">Int32</span> IndexOf(T item)
        {
            <span style="color:blue;">return</span> nodes_.IndexOf(item);
        }

        <span style="color:blue;">#endregion</span>
    }
}</pre>
<p><span style="font-family:Tahoma;font-weight:bold;">A Custom MSBuild Task for Topological Sort</span></p>
<p>The preceding class can be used in a custom MSBuild task in order to sort the corresponding projects in the order (or reverse order) of dependencies:</p>
<pre><span style="color:blue;">using</span> System;
<span style="color:blue;">using</span> System.Collections;
<span style="color:blue;">using</span> System.Collections.Generic;
<span style="color:blue;">using</span> System.IO;
<span style="color:blue;">using</span> System.Linq;

<span style="color:blue;">using</span> Microsoft.Build.Framework;
<span style="color:blue;">using</span> Microsoft.Build.Utilities;

<span style="color:blue;">namespace</span> BizTalkFactory.Automation
{
    <span style="color:blue;">public</span> <span style="color:blue;">class</span> SortDependentProject : <span style="color:lightseagreen;">Task</span>
    {
        <span style="color:blue;">private</span> <span style="color:blue;">bool</span> most_dependent_ = <span style="color:blue;">false</span>;
        <span style="color:blue;">private</span> <span style="color:lightseagreen;">ITaskItem</span>[] outputs_ = <span style="color:blue;">new</span> <span style="color:lightseagreen;">ITaskItem</span>[]{};

        [<span style="color:lightseagreen;">Required</span>]
        <span style="color:blue;">public</span> <span style="color:lightseagreen;">ITaskItem</span>[] Project { <span style="color:blue;">get</span>; <span style="color:blue;">set</span>; }

        [<span style="color:lightseagreen;">Output</span>]
        <span style="color:blue;">public</span> <span style="color:lightseagreen;">ITaskItem</span>[] TargetOutputs
        {
            <span style="color:blue;">get</span>
            {
                <span style="color:blue;">return</span> outputs_;
            }
            <span style="color:blue;">set</span>
            {
                outputs_ = <span style="color:blue;">value</span>;
            }
        }

        <span style="color:blue;">public</span> <span style="color:lightseagreen;">Boolean</span> MostDependentFirst
        {
            <span style="color:blue;">get</span> { <span style="color:blue;">return</span> most_dependent_; }
            <span style="color:blue;">set</span> { most_dependent_ = <span style="color:blue;">value</span>; }
        }

        <span style="color:blue;">#region</span><span style="color:gray;"> Overrides</span>

        <span style="color:blue;">public</span> <span style="color:blue;">override</span> <span style="color:blue;">bool</span> Execute()
        {
            <span style="color:blue;">if</span> (Project.Length == 0)
                outputs_ = Project;

            <span style="color:lightseagreen;">Graph</span>&lt;<span style="color:lightseagreen;">String</span>&gt; graph = <span style="color:blue;">new</span> <span style="color:lightseagreen;">Graph</span>&lt;<span style="color:blue;">string</span>&gt;();

            <span style="color:blue;">foreach</span> (<span style="color:lightseagreen;">ITaskItem</span> item <span style="color:blue;">in</span> Project)
            {
                <span style="color:blue;">string</span> dependencies = (<span style="color:blue;">string</span>)item.GetMetadata(<span style="color:maroon;">"ProjectReference"</span>);
                <span style="color:blue;">string</span>[] references = Canonicalize(<span style="color:lightseagreen;">Path</span>.GetDirectoryName(item.ItemSpec), dependencies);
                <span style="color:blue;">foreach</span> (<span style="color:blue;">string</span> reference <span style="color:blue;">in</span> references)
                    <span style="color:blue;">if</span> (<span style="color:lightseagreen;">String</span>.IsNullOrEmpty(reference))
                        graph.AddNode(item.ItemSpec);
                    <span style="color:blue;">else</span>
                        graph.AddEdge(item.ItemSpec, reference);
            }

            <span style="color:lightseagreen;">List</span>&lt;<span style="color:lightseagreen;">ITaskItem</span>&gt; taskItems = <span style="color:blue;">new</span> <span style="color:lightseagreen;">List</span>&lt;<span style="color:lightseagreen;">ITaskItem</span>&gt;(Project.Length);

            <span style="color:blue;">foreach</span> (<span style="color:lightseagreen;">String</span> item <span style="color:blue;">in</span> graph.Sort(most_dependent_))
            {
                <span style="color:lightseagreen;">TaskItem</span> taskItem = <span style="color:blue;">new</span> <span style="color:lightseagreen;">TaskItem</span>();
                taskItem.ItemSpec = item;

                <span style="color:lightseagreen;">ITaskItem</span> sourceItem = Project.Single(element =&gt; element.ItemSpec == taskItem.ItemSpec);
                sourceItem.CopyMetadataTo(taskItem);

                taskItems.Add(taskItem);
            }

            outputs_ = taskItems.ToArray();
            <span style="color:blue;">return</span> <span style="color:blue;">true</span>;
        }

        <span style="color:blue;">#endregion</span>

        <span style="color:blue;">#region</span><span style="color:gray;"> Implementation</span>

        <span style="color:blue;">private</span> <span style="color:blue;">string</span>[] Canonicalize(<span style="color:blue;">string</span> relativeRoot, <span style="color:blue;">string</span> path)
        {
            <span style="color:blue;">if</span> (<span style="color:lightseagreen;">String</span>.IsNullOrEmpty(path))
                <span style="color:blue;">return</span> <span style="color:blue;">new</span> <span style="color:blue;">string</span>[]{ path };

            <span style="color:lightseagreen;">List</span>&lt;<span style="color:lightseagreen;">String</span>&gt; strings = <span style="color:blue;">new</span> <span style="color:lightseagreen;">List</span>&lt;<span style="color:lightseagreen;">String</span>&gt;();

            <span style="color:blue;">foreach</span> (<span style="color:blue;">string</span> item <span style="color:blue;">in</span> path.Split(<span style="color:blue;">new</span> <span style="color:blue;">char</span>[] { ';' }))
            {

                <span style="color:blue;">if</span> (<span style="color:lightseagreen;">Path</span>.IsPathRooted(item) &amp;&amp; File.Exists(item))
                    strings.Add(item);

                <span style="color:blue;">string</span> resolved = <span style="color:lightseagreen;">Path</span>.GetFullPath(<span style="color:lightseagreen;">Path</span>.Combine(relativeRoot, item));

                <span style="color:blue;">if</span> (File.Exists(resolved))
                    strings.Add(resolved);
            }

            <span style="color:blue;">return</span> strings.ToArray();
        }

        <span style="color:blue;">#endregion</span>
    }
}</pre>
<p>This custom task would be used simply in an MSBuild project file like so:</p>
<pre style="border:#cecece 1px solid;background-color:#fbfbfb;width:100%;font-family:consolas, 'Courier New', courier, monospace;font-size:12px;margin:0;padding:5px 1em;">    <span style="color:green;">&lt;!-- Calculate projects in order of dependencies --&gt;</span>

    <span style="color:blue;">&lt;</span><span style="color:maroon;">MSBuild</span> <span style="color:red;">Projects</span>=<span style="color:blue;">"$(MSBuildProjectFile)"</span> <span style="color:red;">Targets</span>=<span style="color:blue;">"_ComputeProjectReference"</span> /<span style="color:blue;">&gt;</span>

    <span style="color:blue;">&lt;</span><span style="color:maroon;">CustomTask.Automation.SortDependentProject</span>
        <span style="color:red;">Project</span>=<span style="color:blue;">"@(ProjectReference)"</span>
        <span style="color:red;">MostDependentFirst</span>=<span style="color:blue;">"$(Clean)"</span><span style="color:blue;">&gt;</span>
      <span style="color:blue;">&lt;</span><span style="color:maroon;">Output</span> <span style="color:red;">TaskParameter</span>=<span style="color:blue;">"TargetOutputs"</span> <span style="color:red;">ItemName</span>=<span style="color:blue;">"ProjectDependencies"</span> /<span style="color:blue;">&gt;</span>
    <span style="color:blue;">&lt;</span>/<span style="color:maroon;">CustomTask.Automation.SortDependentProject</span><span style="color:blue;">&gt;</span>

    <span style="color:blue;">&lt;</span><span style="color:maroon;">ItemGroup</span><span style="color:blue;">&gt;</span>
      <span style="color:blue;">&lt;</span><span style="color:maroon;">Project</span> <span style="color:red;">Remove</span>=<span style="color:blue;">"@(Project)"</span> /<span style="color:blue;">&gt;</span>
      <span style="color:blue;">&lt;</span><span style="color:maroon;">Project</span> <span style="color:red;">Include</span>=<span style="color:blue;">"@(ProjectDependencies)"</span> /<span style="color:blue;">&gt;</span>
    <span style="color:blue;">&lt;</span>/<span style="color:maroon;">ItemGroup</span><span style="color:blue;">&gt;</span></pre>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maximelabelle.wordpress.com/355/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maximelabelle.wordpress.com/355/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maximelabelle.wordpress.com/355/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maximelabelle.wordpress.com/355/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maximelabelle.wordpress.com/355/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maximelabelle.wordpress.com/355/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maximelabelle.wordpress.com/355/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maximelabelle.wordpress.com/355/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maximelabelle.wordpress.com/355/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maximelabelle.wordpress.com/355/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maximelabelle.wordpress.com/355/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maximelabelle.wordpress.com/355/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maximelabelle.wordpress.com/355/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maximelabelle.wordpress.com/355/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&amp;blog=16599311&amp;post=355&amp;subd=maximelabelle&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maximelabelle.wordpress.com/2011/11/29/building-multiple-projects-in-order-with-msbuild/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4c7bbc359fc392f6afd584cf99a5b427?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maximelabelle</media:title>
		</media:content>
	</item>
		<item>
		<title>Enabling Incremental Compilation of BizTalk .btproj MSBuild Files</title>
		<link>http://maximelabelle.wordpress.com/2011/10/26/enabling-incremental-compilation-of-biztalk-btproj-msbuild-files/</link>
		<comments>http://maximelabelle.wordpress.com/2011/10/26/enabling-incremental-compilation-of-biztalk-btproj-msbuild-files/#comments</comments>
		<pubDate>Wed, 26 Oct 2011 16:04:14 +0000</pubDate>
		<dc:creator>Maxime Labelle</dc:creator>
				<category><![CDATA[BizTalk]]></category>
		<category><![CDATA[MSBuild]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://maximelabelle.wordpress.com/?p=332</guid>
		<description><![CDATA[Since BizTalk Server 2009, BizTalk Server project files are MSBuild .btproj XML files. For some reason, BizTalk projects need to be compiled in two phases. The first pass compiles schemas, maps and pipelines, and produces an intermediate managed assembly. The &#8230; <a href="http://maximelabelle.wordpress.com/2011/10/26/enabling-incremental-compilation-of-biztalk-btproj-msbuild-files/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&amp;blog=16599311&amp;post=332&amp;subd=maximelabelle&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Since BizTalk Server 2009, BizTalk Server project files are <a href="http://msdn.microsoft.com/en-us/library/ms171452(v=vs.80).aspx">MSBuild</a> .btproj XML files.</p>
<p>For some reason, BizTalk projects need to be compiled in two phases.</p>
<p>
The first pass compiles schemas, maps and pipelines, and produces an intermediate managed assembly. The second pass deletes the intermediate assembly, compiles the orchestrations and produces the final output assembly.</p>
<p>
This behavior is hardcoded in the <span style="font-family:'Courier New';">$(MSBuildExtensionsPath)\Microsoft\BizTalk\BizTalkC.targets file</span>.</p>
<p>
Unfortunately, this breaks incremental compilation of large solutions that make use of BizTalk Server projects because it forces a recompile each time a project is being built. Fortunately, there is a solution.</p>
<p>
MSBuild being extensible, it is possible to override the default (incorrect) targets and fix this. First, create an appropriate file, say <span style="font-family:'Courier New';">BizTalkCustom.targets</span> to host your customizations, in any location of your choice :</p>
<pre style="border:#cecece 1px solid;background-color:#fbfbfb;width:100%;font-family:consolas, 'Courier New', courier, monospace;font-size:12px;margin:0;padding:5px 1em;">
  <span style="color:green;">&lt;!-- Rerun the build process (second pass) if the project hosts orchestrations --&gt;</span>
  <span style="color:green;">&lt;!-- The extra &lt;&lt; and @(CSharpOutputFromXLang)!='' &gt;&gt; condition prevents this task --&gt;</span>
  <span style="color:green;">&lt;!-- from taking place if the project does not contain any orchestrations.  --&gt;</span>
  <span style="color:blue;">&lt;</span><span style="color:maroon;">Target</span> <span style="color:red;">Name</span><span style="color:blue;">="SecondPass"</span> <span style="color:red;">Condition</span><span style="color:blue;">="$(SecondBuild)!=true and $(TempAssemblyOnly)!=true and @(XLang)!=''"</span><span style="color:blue;">&gt;</span>
    <span style="color:blue;">&lt;</span><span style="color:maroon;">MSBuild</span> <span style="color:red;">Projects</span><span style="color:blue;">="$(MSBuildProjectFile)"</span> <span style="color:red;">Properties</span><span style="color:blue;">="SecondBuild=true"</span> /<span style="color:blue;">&gt;</span>
  <span style="color:blue;">&lt;</span>/<span style="color:maroon;">Target</span><span style="color:blue;">&gt;</span>

  <span style="color:green;">&lt;!-- Compile XLang/s orchestration --&gt;</span>
  <span style="color:green;">&lt;!-- Notice that is the MSBuild system has decided to run this Target, --&gt;</span>
  <span style="color:green;">&lt;!-- both intermediately compiled files and intermediately compiled assembly are deleted. --&gt;</span>
  <span style="color:blue;">&lt;</span><span style="color:maroon;">Target</span>
    <span style="color:red;">Name</span><span style="color:blue;">="CompileODX"</span>
    <span style="color:red;">Condition</span><span style="color:blue;">="$(SecondBuild)==true"</span>
    <span style="color:red;">Inputs</span><span style="color:blue;">="@(XLang);$(MSBuildAllProjects);$(ClrTypesAssembly)"</span>
    <span style="color:red;">Outputs</span><span style="color:blue;">="$(BuildDone)"</span><span style="color:blue;">&gt;</span>

    <span style="color:green;">&lt;!-- Delete previously generated C# files from XLang compilation --&gt;</span>
    <span style="color:blue;">&lt;</span><span style="color:maroon;">Delete</span> <span style="color:red;">Files</span>="@(IntermediateAssembly)" /<span style="color:blue;">&gt;</span>
    <span style="color:blue;">&lt;</span><span style="color:maroon;">Delete</span> <span style="color:red;">Files</span>="@(CSharpOutputFromXLang)" /<span style="color:blue;">&gt;</span>

    <span style="color:blue;">&lt;</span><span style="color:maroon;">XLangTask</span> XLangItems="@(XLang)"
               <span style="color:red;">ProjectReferences</span><span style="color:blue;">="@(ReferencePath)"</span>
               <span style="color:red;">WarningLevel</span><span style="color:blue;">="$(WarningLevel)"</span>
               <span style="color:red;">BpelCompliance</span><span style="color:blue;">="$(BpelCompliance)"</span>
               <span style="color:red;">DefineConstants</span><span style="color:blue;">="$(DefineConstants)"</span>
               <span style="color:red;">TreatWarningsAsErrors</span><span style="color:blue;">="$(TreatWarningsAsErrors)"</span>
               <span style="color:red;">TempAssembly</span><span style="color:blue;">="$(ClrTypesAssembly)"</span>
               <span style="color:red;">OutputDirectory</span><span style="color:blue;">="$(XLangOutputPath)"</span><span style="color:blue;">&gt;</span>

    <span style="color:blue;">&lt;</span>/<span style="color:maroon;">XLangTask</span><span style="color:blue;">&gt;</span>
  <span style="color:blue;">&lt;</span>/<span style="color:maroon;">Target</span><span style="color:blue;">&gt;</span>
</pre>
<p>
The first part of the solution is to modify the <span style="font-family:'Courier New';">&lt;SecondPass&gt;</span> Target in order to add an extra test in the <span style="font-family:'Courier New';">&lt;<span style="color:red;">Condition</span>&gt;</span> attribute. This prevents the SecondPass from even taking place in case your .btproj does not host orchestrations.</p>
<p>
The second part of the solution is to defer the removal of the intermediate managed assembly to the <span style="font-family:'Courier New';">&lt;<span style="color:red;">CompileODX</span>&gt;</span> target. Indeed, this target correctly handles incremental compilation, so it does not run if all files are already up-to-date.</p>
<p>
In order to use the overriden targets in your compilations, you need to slightly modify your .btproj project files, and import the preceding .targets file, like so:</p>
<pre style="border:#cecece 1px solid;background-color:#fbfbfb;width:100%;font-family:consolas, 'Courier New', courier, monospace;font-size:12px;margin:0;padding:5px 1em;">
<span style="color:blue;">&lt;</span><span style="color:maroon;">Import</span> <span style="color:red;">Project</span><span style="color:blue;">="$(MSBuildBinPath)\Microsoft.CSharp.targets"</span> /<span style="color:blue;">&gt;</span>
<span style="color:blue;">&lt;</span><span style="color:maroon;">Import</span> <span style="color:red;">Project</span><span style="color:blue;">="$(MSBuildExtensionsPath)\Microsoft\BizTalk\BizTalkC.targets"</span> /<span style="color:blue;">&gt;</span>
<strong><span style="color:blue;">&lt;</span><span style="color:maroon;">Import</span>
    <span style="color:red;">Condition</span><span style="color:blue;">=" Exists('$(CustomExtensionsPath)BizTalkCustom.targets') "</span>
    <span style="color:red;">Project</span><span style="color:blue;">="$(CustomExtensionsPath)BizTalkCustom.targets"</span> /<span style="color:blue;">&gt;</span></strong>
</pre>
<p>
Where <span>$(CustomExtensionsPath)</span> represents the path to your custom extensions project files.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maximelabelle.wordpress.com/332/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maximelabelle.wordpress.com/332/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maximelabelle.wordpress.com/332/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maximelabelle.wordpress.com/332/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maximelabelle.wordpress.com/332/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maximelabelle.wordpress.com/332/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maximelabelle.wordpress.com/332/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maximelabelle.wordpress.com/332/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maximelabelle.wordpress.com/332/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maximelabelle.wordpress.com/332/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maximelabelle.wordpress.com/332/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maximelabelle.wordpress.com/332/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maximelabelle.wordpress.com/332/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maximelabelle.wordpress.com/332/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&amp;blog=16599311&amp;post=332&amp;subd=maximelabelle&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maximelabelle.wordpress.com/2011/10/26/enabling-incremental-compilation-of-biztalk-btproj-msbuild-files/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4c7bbc359fc392f6afd584cf99a5b427?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maximelabelle</media:title>
		</media:content>
	</item>
		<item>
		<title>//BUILD Conference &#8211; Anaheim California &#8211; Days 3 and 4</title>
		<link>http://maximelabelle.wordpress.com/2011/09/16/build-conference-anaheim-california-day-3/</link>
		<comments>http://maximelabelle.wordpress.com/2011/09/16/build-conference-anaheim-california-day-3/#comments</comments>
		<pubDate>Fri, 16 Sep 2011 09:45:32 +0000</pubDate>
		<dc:creator>Maxime Labelle</dc:creator>
				<category><![CDATA[Non classé]]></category>

		<guid isPermaLink="false">https://maximelabelle.wordpress.com/2011/09/13/build-conference-anaheim-california-day-3/</guid>
		<description><![CDATA[The last two days of the BUILD conference here in Anaheim are all about the breakout sessions. This concludes a session-packed week that gave all of us, developers, architects, managers and the world at large what the ambitions of Microsoft &#8230; <a href="http://maximelabelle.wordpress.com/2011/09/16/build-conference-anaheim-california-day-3/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&amp;blog=16599311&amp;post=307&amp;subd=maximelabelle&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The last two days of the BUILD conference here in Anaheim are all about the breakout sessions.</p>
<p>This concludes a session-packed week that gave all of us, developers, architects, managers and the world at large what the ambitions of Microsoft are for the future.</p>
<p>It&#8217;s an interesting and exciting moment and situation to be in, because we are the ones with this opportunity to lead the transformation of the way computers and devices are used, connected and consumed.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maximelabelle.wordpress.com/307/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maximelabelle.wordpress.com/307/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maximelabelle.wordpress.com/307/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maximelabelle.wordpress.com/307/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maximelabelle.wordpress.com/307/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maximelabelle.wordpress.com/307/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maximelabelle.wordpress.com/307/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maximelabelle.wordpress.com/307/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maximelabelle.wordpress.com/307/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maximelabelle.wordpress.com/307/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maximelabelle.wordpress.com/307/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maximelabelle.wordpress.com/307/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maximelabelle.wordpress.com/307/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maximelabelle.wordpress.com/307/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&amp;blog=16599311&amp;post=307&amp;subd=maximelabelle&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maximelabelle.wordpress.com/2011/09/16/build-conference-anaheim-california-day-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4c7bbc359fc392f6afd584cf99a5b427?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maximelabelle</media:title>
		</media:content>
	</item>
		<item>
		<title>//BUILD Conference &#8211; Anaheim California &#8211; Day 2</title>
		<link>http://maximelabelle.wordpress.com/2011/09/14/build-conference-anaheim-california-day-2/</link>
		<comments>http://maximelabelle.wordpress.com/2011/09/14/build-conference-anaheim-california-day-2/#comments</comments>
		<pubDate>Wed, 14 Sep 2011 09:45:23 +0000</pubDate>
		<dc:creator>Maxime Labelle</dc:creator>
				<category><![CDATA[Non classé]]></category>

		<guid isPermaLink="false">https://maximelabelle.wordpress.com/2011/09/13/build-conference-anaheim-california-day-2/</guid>
		<description><![CDATA[Day 2 at the BUILD conference was all about the breakout sessions. Sessions about Windows Server. Sessions about Visual Studio, Team Foundation Service, and Application Lifecycle Management. And, of course, sessions about building great Metro style applications for the upcoming &#8230; <a href="http://maximelabelle.wordpress.com/2011/09/14/build-conference-anaheim-california-day-2/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&amp;blog=16599311&amp;post=306&amp;subd=maximelabelle&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Day 2 at the BUILD conference was all about the breakout sessions. Sessions about Windows Server. Sessions about Visual Studio, Team Foundation Service, and Application Lifecycle Management. And, of course, sessions about building great Metro style applications for the upcoming Windows 8.</p>
<p>But the critical main thought was delivered as part of the day&#8217;s opening Keynote:</p>
<div style="border-bottom:#cecece 1px solid;border-left:#cecece 1px solid;background-color:#fbfbfb;border-top:#cecece 1px solid;border-right:#cecece 1px solid;margin:40px;padding:1em;">
<p>This is the day and age of the Developers!<br />
This is the day and age of the <em>Windows</em> Developers! (&#8230;)<br />
Developers, Developers, Developers!</p>
<p style="text-align:right;"><span style="font-weight:Bold;">Steve Ballmer<br />CEO, Microsoft Corporation.</span></p>
</div>
<p>I think this summarizes very well what the strategy of Microsoft comes down to for the years ahead.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maximelabelle.wordpress.com/306/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maximelabelle.wordpress.com/306/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maximelabelle.wordpress.com/306/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maximelabelle.wordpress.com/306/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maximelabelle.wordpress.com/306/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maximelabelle.wordpress.com/306/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maximelabelle.wordpress.com/306/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maximelabelle.wordpress.com/306/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maximelabelle.wordpress.com/306/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maximelabelle.wordpress.com/306/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maximelabelle.wordpress.com/306/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maximelabelle.wordpress.com/306/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maximelabelle.wordpress.com/306/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maximelabelle.wordpress.com/306/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&amp;blog=16599311&amp;post=306&amp;subd=maximelabelle&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maximelabelle.wordpress.com/2011/09/14/build-conference-anaheim-california-day-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4c7bbc359fc392f6afd584cf99a5b427?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maximelabelle</media:title>
		</media:content>
	</item>
		<item>
		<title>//BUILD Conference &#8211; Anaheim California &#8211; Day 1</title>
		<link>http://maximelabelle.wordpress.com/2011/09/13/build-conference-anaheim-california-day-1/</link>
		<comments>http://maximelabelle.wordpress.com/2011/09/13/build-conference-anaheim-california-day-1/#comments</comments>
		<pubDate>Tue, 13 Sep 2011 09:46:53 +0000</pubDate>
		<dc:creator>Maxime Labelle</dc:creator>
				<category><![CDATA[Non classé]]></category>

		<guid isPermaLink="false">https://maximelabelle.wordpress.com/?p=304</guid>
		<description><![CDATA[Not many things have been shared by Microsoft ahead of this event. Today we are provided with a &#8220;Big Picture&#8221; overview of what&#8217;s up next, in the form of a introduction Keynote, followed by three Big Picture sessions. Keynote What &#8230; <a href="http://maximelabelle.wordpress.com/2011/09/13/build-conference-anaheim-california-day-1/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&amp;blog=16599311&amp;post=304&amp;subd=maximelabelle&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Not many things have been shared by Microsoft ahead of this event. Today we are provided with a &#8220;Big Picture&#8221; overview of what&#8217;s up next, in the form of a introduction Keynote, followed by three Big Picture sessions.</p>
<p><span style="font-family:Tahoma;"><span style="font-weight:bold;">Keynote</span></span></p>
<p>What we&#8217;ve seen today:</p>
<p>A showcase of the new Metro-Style user interface. This touch-first interface, first seen on the Zune and recent Windows Phone devices, has been significantly enhanced. It runs on many devices, in a variety of shapes and sizes, including ARM-based tablets and phones.</p>
<p>What powers the new Metro user-interface is the pervasive use of HTML 5 and Javascript, supported nativelely by the new Internet Explorer 10 rendering engine.</p>
<p>A whole host of improvements, both in the core architecture of Windows and in the user interface. Because, indeed, the existing user interface is still there and protects the massive investment that has been made on Windows over the years.</p>
<p>Last, but not least, Microsoft has given away the full suite of Developer&#8217;s Preview Software stack &#8211; Windows 8, Visual Studio 11, etc. &#8211; bundled on, what they call the Developer&#8217;s Preview Hardware: a brand new Core i5 Samsung Windows 8 Tablet!</p>
<p>This most anticipated piece of hardware was demoed live and will definitely prove to be a major contender against competing offerings from Apple and Google.</p>
<p>By giving away the Developer&#8217;s Preview Hardware tablet, Microsoft hopes to create a vast ecosytem of applications, ready to be downloaded from the upcoming Windows Store when the platform ships, probably around spring next year.</p>
<p>In fact, by bringing support for both Multi-Touch and Stylus-based Input to Windows, and allow for seamless co-existing Metro-Style and Desktop applications, this platform will certainly appeal to professionnals and consumers alike with a compelling set of applications.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maximelabelle.wordpress.com/304/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maximelabelle.wordpress.com/304/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maximelabelle.wordpress.com/304/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maximelabelle.wordpress.com/304/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maximelabelle.wordpress.com/304/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maximelabelle.wordpress.com/304/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maximelabelle.wordpress.com/304/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maximelabelle.wordpress.com/304/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maximelabelle.wordpress.com/304/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maximelabelle.wordpress.com/304/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maximelabelle.wordpress.com/304/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maximelabelle.wordpress.com/304/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maximelabelle.wordpress.com/304/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maximelabelle.wordpress.com/304/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&amp;blog=16599311&amp;post=304&amp;subd=maximelabelle&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maximelabelle.wordpress.com/2011/09/13/build-conference-anaheim-california-day-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4c7bbc359fc392f6afd584cf99a5b427?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maximelabelle</media:title>
		</media:content>
	</item>
		<item>
		<title>//BUILD Conference &#8211; Anaheim California</title>
		<link>http://maximelabelle.wordpress.com/2011/09/13/build-conference-anaheim-california-2/</link>
		<comments>http://maximelabelle.wordpress.com/2011/09/13/build-conference-anaheim-california-2/#comments</comments>
		<pubDate>Mon, 12 Sep 2011 22:00:52 +0000</pubDate>
		<dc:creator>Maxime Labelle</dc:creator>
				<category><![CDATA[Non classé]]></category>

		<guid isPermaLink="false">http://maximelabelle.wordpress.com/?p=299</guid>
		<description><![CDATA[After a comfortable but lonnnng flight, I&#8217;m in! More famously known for its DisneyLand Resort, Anaheim is getting busy today, with many attendees converging to register at the Convention Center, in preparation of the upcoming conference, where Microsoft promises to &#8230; <a href="http://maximelabelle.wordpress.com/2011/09/13/build-conference-anaheim-california-2/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&amp;blog=16599311&amp;post=299&amp;subd=maximelabelle&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>After a comfortable but lonnnng flight, I&#8217;m in!
</p>
<p style="text-align:center;"><a href="http://maximelabelle.files.wordpress.com/2011/09/image.jpeg"><img src="http://maximelabelle.files.wordpress.com/2011/09/image.jpeg?w=640&#038;h=478" alt="" title="image" width="640" height="478" class="alignnone size-full wp-image-300" /></a></p>
<p>More famously known for its DisneyLand Resort, Anaheim is getting busy today, with many attendees converging to register at the Convention Center, in preparation of the upcoming conference, where Microsoft promises to unveil the future of Windows.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maximelabelle.wordpress.com/299/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maximelabelle.wordpress.com/299/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maximelabelle.wordpress.com/299/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maximelabelle.wordpress.com/299/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maximelabelle.wordpress.com/299/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maximelabelle.wordpress.com/299/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maximelabelle.wordpress.com/299/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maximelabelle.wordpress.com/299/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maximelabelle.wordpress.com/299/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maximelabelle.wordpress.com/299/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maximelabelle.wordpress.com/299/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maximelabelle.wordpress.com/299/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maximelabelle.wordpress.com/299/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maximelabelle.wordpress.com/299/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&amp;blog=16599311&amp;post=299&amp;subd=maximelabelle&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maximelabelle.wordpress.com/2011/09/13/build-conference-anaheim-california-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4c7bbc359fc392f6afd584cf99a5b427?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maximelabelle</media:title>
		</media:content>

		<media:content url="http://maximelabelle.files.wordpress.com/2011/09/image.jpeg" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
		<item>
		<title>Debugging XSLT Stylesheet with Custom Extension Objects from Within Visual Studio</title>
		<link>http://maximelabelle.wordpress.com/2011/09/09/debugging-xslt-stylesheet-with-custom-extension-objects-from-within-visual-studio/</link>
		<comments>http://maximelabelle.wordpress.com/2011/09/09/debugging-xslt-stylesheet-with-custom-extension-objects-from-within-visual-studio/#comments</comments>
		<pubDate>Fri, 09 Sep 2011 12:19:35 +0000</pubDate>
		<dc:creator>Maxime Labelle</dc:creator>
				<category><![CDATA[BizTalk]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://maximelabelle.wordpress.com/?p=290</guid>
		<description><![CDATA[When developping complex maps with the BizTalk Mapper, you sometimes find yourself in a situation where you need to debug the underlying logic of the associated XML stylesheet. In situations like these, it is customary to have Visual Studio generate &#8230; <a href="http://maximelabelle.wordpress.com/2011/09/09/debugging-xslt-stylesheet-with-custom-extension-objects-from-within-visual-studio/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&amp;blog=16599311&amp;post=290&amp;subd=maximelabelle&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>
When developping complex maps with the BizTalk Mapper, you sometimes find yourself in a situation where you need to debug the underlying logic of the associated XML stylesheet.</p>
<p>
In situations like these, it is customary to have Visual Studio generate an XSLT file from the BizTalk map, and use Visual Studio&#8217;s builtin support for debugging XSLT. This allows you to put breakpoints, inspect the content of variables and precisely monitor the transformation step by step.</p>
<p><span style="font-family:Tahoma;"><span style="font-weight:bold;">Custom Extension Objects</span></span></p>
<p>
There are two cases, however, that prevent you from debugging the underlying XSLT from within Visual Studio :</p>
<p>
The first case involves the use of the various database functoids, for instance the cross-reference GetCommonValue, GetCommonID, GetApplicationValue and GetApplicationID functoids. These, are implemented in terms of external functions, in a separate assembly, that is itself referenced from the generated map.</p>
<p>
The second case involves the use of the Scripting functoid to call an external function. This is a variation of the first case in which you specify the function you want to call.</p>
<p>
In order to execute such maps, the BizTalk Mapper uses the <a href="http://msdn.microsoft.com/fr-fr/library/system.xml.xsl.xsltransform(v=vs.80).aspx">XslTransform</a> class by supplying a list of all the classes whose methods are required to carry out the XSLT transformation, along with their associated namespace prefixes.</p>
<p>
The set of such custom classes used to provide external logic to XLST transformations is referred to as Custom XSLT Extension Objects. At design-time, these Custom Extension Objects are represented as an additional file that contains the associations between the declared XML namespace prefixes and the fully qualified .Net type names of the classes which contain the methods called from the map.</p>
<p>
When you invoke the &#8220;Validate Map&#8221; context-menu option on a BizTalk Map in Visual Studio, you will notice that BizTalk generates this file, with a _extxml.xml suffix along with the associated XSLT.</p>
<p>
Most of the time, this file is empty, for basic maps. This is not the case, however, if the map makes use of external functions in separate assemblies, as alluded to in the two cases described above.</p>
<p><span style="font-family:Tahoma;"><span style="font-weight:bold;">Debugging XSLT with Custom Extension Objects</span></span></p>
<p>
Unfortunately, such maps seemingly cannot be debugged inside Visual Studio without modifications. If you use Visual Studio&#8217;s builtin XSLT debugger and attempt to step into the underlying XSLT file, you will encounter an error such as this one:</p>
<pre style="font-family:'Courier New';">
---------------------
Cannot find the script or external object that implements prefix
'http://schemas.microsoft.com/BizTalk/2003/ScriptNS0'. "
</pre>
<p>
Even though Visual Studio generates both an XSLT file and a _EXTXML.XML file, it seems there is no way to instruct Visual Studio about the custom extension objects file, which makes the debugging experience cumbersome and very frustrating.</p>
<p>
Fortunately, there <em>is</em> a way!</p>
<p>
Although there are no options in the Visual Studio GUI, all the support is there in the .Net Framework. All there is do is write a little C# program to do the trick.</p>
<p><span style="font-family:Tahoma;"><span style="font-weight:bold;">A Simple Function to Debug Custom XLST Maps</span></span></p>
<p>
The following function is very simple. In real life, this function would be compiled into a C# program with additional logic to accept and parse command-line arguments, in order to be able to supply paths to the stylesheet, the extension objects file and the input and output documents. This is no rocket science.</p>
<p>
Here is the code:</p>
<pre style="border:#cecece 1px solid;background-color:#fbfbfb;margin:40px;padding:1em;">
<pre style="padding-top:5px;padding-bottom:5px;width:100%;font-family:consolas, 'Courier New', courier, monospace;font-size:12px;margin:0;">
<span style="color:blue;">using</span> System;
<span style="color:blue;">using</span> System.Collections;
<span style="color:blue;">using</span> System.IO;
<span style="color:blue;">using</span> System.Reflection;
<span style="color:blue;">using</span> System.Text;
<span style="color:blue;">using</span> System.Xml;
<span style="color:blue;">using</span> System.Xml.Xsl;

<span style="color:blue;">class</span> <span style="color:lightseagreen;">DebugHelper</span>
{
  <span style="color:blue;">static</span> <span style="color:blue;">void</span> Main(<span style="color:blue;">string</span>[] args)
  {
    <span style="color:blue;">string</span> input = <span style="color:maroon;">@"...\input.xml"</span>;
    <span style="color:blue;">string</span> output = Path.ChangeExtension(input, <span style="color:maroon;">".<span style="color:blue;">out</span>"</span>);

    <span style="color:blue;">string</span> stylesheet = <span style="color:maroon;">@"...\stylesheet.xslt"</span>;
    <span style="color:blue;">string</span> extension_object = <span style="color:maroon;">@"...\extension_extxml.xml"</span>;

    <span style="color:blue;">string</span> result = TransformXslt(input, stylesheet, extension_object);
  }

  <span style="color:blue;">private</span> <span style="color:blue;">static</span> <span style="color:blue;">string</span> TransformXslt(<span style="color:blue;">string</span> document, <span style="color:blue;">string</span> stylesheet, <span style="color:blue;">string</span> extension)
  {
    <span style="color:blue;">return</span> TransformXslt(document, stylesheet, ParseExtension(extension));
  }

  <span style="color:blue;">private</span> <span style="color:blue;">static</span> <span style="color:blue;">string</span> TransformXslt(<span style="color:blue;">string</span> document, <span style="color:blue;">string</span> stylesheet, <span style="color:blue;">object</span>[] extension)
  {
    <span style="color:lightseagreen;">XslCompiledTransform</span> transform = <span style="color:blue;">new</span> <span style="color:lightseagreen;">XslCompiledTransform</span>(<span style="color:blue;">true</span>);
    transform.Load(stylesheet, <span style="color:blue;">new</span> <span style="color:lightseagreen;">XsltSettings</span>(<span style="color:blue;">true</span>, <span style="color:blue;">true</span>), <span style="color:blue;">null</span>);

    <span style="color:lightseagreen;">XsltArgumentList</span> arguments = <span style="color:blue;">new</span> <span style="color:lightseagreen;">XsltArgumentList</span>();

    <span style="color:blue;">for</span> (<span style="color:blue;">int</span> index = 0; index &lt; extension.Length; index += 2)
    {
      arguments.AddExtensionObject(
        extension[index] as <span style="color:blue;">string</span>,
        extension[index + 1]
        );
    }

    <span style="color:lightseagreen;">StringBuilder</span> output = <span style="color:blue;">new</span> <span style="color:lightseagreen;">StringBuilder</span>();

    <span style="color:blue;">using</span> (<span style="color:lightseagreen;">XmlWriter</span> writer = <span style="color:lightseagreen;">XmlWriter</span>.Create(output, transform.OutputSettings))
      transform.Transform(document, arguments, writer);

    <span style="color:blue;">return</span> output.ToString();
  }

  <span style="color:blue;">private</span> <span style="color:blue;">static</span> <span style="color:blue;">object</span>[] ParseExtension(<span style="color:blue;">string</span> extension)
  {
    <span style="color:blue;">if</span> (<span style="color:lightseagreen;">String</span>.IsNullOrEmpty(extension))
      <span style="color:blue;">return</span> <span style="color:blue;">new</span> <span style="color:blue;">object</span>[]{};

    <span style="color:lightseagreen;">XmlDocument</span> document = <span style="color:blue;">new</span> <span style="color:lightseagreen;">XmlDocument</span>();
    document.Load(extension);

    ArrayList extensions = <span style="color:blue;">new</span> ArrayList();

    <span style="color:blue;">foreach</span> (<span style="color:lightseagreen;">XmlNode</span> node <span style="color:blue;">in</span> document.SelectNodes(<span style="color:maroon;">"/ExtensionObjects/ExtensionObject"</span>))
    {
      <span style="color:blue;">string</span> extension_namespace = node.Attributes[<span style="color:maroon;">"Namespace"</span>].Value;
      <span style="color:blue;">string</span> extension_assembly = node.Attributes[<span style="color:maroon;">"AssemblyName"</span>].Value;
      <span style="color:blue;">string</span> extension_class = node.Attributes[<span style="color:maroon;">"ClassName"</span>].Value;
      <span style="color:blue;">string</span> assembly_qualified_name = <span style="color:lightseagreen;">String</span>.Format(<span style="color:maroon;">"{0}, {1}"</span>
        , extension_class
        , extension_assembly
        );

      <span style="color:blue;">object</span> extension_object = <span style="color:lightseagreen;">Activator</span>.CreateInstance(<span style="color:lightseagreen;">Type</span>.GetType(assembly_qualified_name));

      extensions.Add(extension_namespace);
      extensions.Add(extension_object);
    }

    <span style="color:blue;">return</span> extensions.ToArray();
  }
}
</pre>
</pre>
<p>
A couple of points of interest need clarification.</p>
<p>
First, the most crucial step, is to use the <a href="http://msdn.microsoft.com/en-us/library/ms163418.aspx">XslCompiledTransform constructor with a first parameter</a> that indicates whether to execute the map in a debugger. This is actually what does the trick in this program.</p>
<p>
When you run the program, it will launch the debugger and break at the beginning of the map. You can add this project to your Visual Studio solution, and you will be able to step into the map directly from the same Visual Studio instance.</p>
<p>
Neat.</p>
<p>
Secondly, what distinguishes this program from Visual Studio&#8217;s builtin XSLT debugger is the ability to actually make use of Custom XSLT Extension Objects.</p>
<p>
The ParseExtensions function has been designed to consume an XML file, whose path is specified in the first argument, that has the same format as the ones generated by Visual Studio when using the &#8220;Validate Map&#8221; option.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maximelabelle.wordpress.com/290/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maximelabelle.wordpress.com/290/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maximelabelle.wordpress.com/290/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maximelabelle.wordpress.com/290/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maximelabelle.wordpress.com/290/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maximelabelle.wordpress.com/290/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maximelabelle.wordpress.com/290/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maximelabelle.wordpress.com/290/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maximelabelle.wordpress.com/290/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maximelabelle.wordpress.com/290/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maximelabelle.wordpress.com/290/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maximelabelle.wordpress.com/290/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maximelabelle.wordpress.com/290/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maximelabelle.wordpress.com/290/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maximelabelle.wordpress.com&amp;blog=16599311&amp;post=290&amp;subd=maximelabelle&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maximelabelle.wordpress.com/2011/09/09/debugging-xslt-stylesheet-with-custom-extension-objects-from-within-visual-studio/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4c7bbc359fc392f6afd584cf99a5b427?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maximelabelle</media:title>
		</media:content>
	</item>
	</channel>
</rss>
