CodeSmith merge functionality for csproj files

If you are seriously using CodeSmith you will know about the merge functionality. True, with introduction of partial classes in .net 2 the need for merging is greatly reduced, but still it is very useful.


How it works, very briefly?


You define markers (start and end, i.e. #region Start and #endregion in C#) in source code and when building template output you pass the marker reference (in this case you would pass a command line argument (it works only from command line) like this: /merge:InsertRegion=”RegionName=Start;Language=C#”. CodeSmith will inject template output between those two markers and will preserve the rest of source code. There are also different merge strategies (insert and preserver out of the box) and moreover, you can define your own if you need to. The same goes for source code support: C#, VB.NET and T-SQL are supported out of the box. If you need additional type of source code you are free to add your own marker definitions using regular expressions. Everything is adequately documented in help file and I won’t repeat it here.


Creating my own target type


Today I realized that I need to inject some text into csproj file itself. The problem is that csproj file (C# project file) isn’t natively supported by CodeSmith. Heck, no problem – CodeSmith is extensible. So I went creating my own merging target: csproj. Since csproj file is an XML one I will define my start marker as <!– NAME–> and end marker as <!– EndRegion–>. Here are the necessary steps:



  • Open CodeSmithEngine.config file located in C:\Documents and Settings\All Users\Application Data\CodeSmith\v3.2 (note that version number might differ)

  • Add the following XML code right after the last node </languageRegionDefinitions>:

    <languageRegionDefinitions>
      <languageKeyList>
        <key>csproj</key>
      </languageKeyList>
      <regionStartRegex>^[ \t]*&lt;!–[\s\t]*(?&lt;name&gt;.*)–&gt;</regionStartRegex>
      <regionEndRegex>^[ \t]*&lt;!–[\s\t]*(?i:EndRegion).*–&gt;</regionEndRegex>
    </languageRegionDefinitions>



  • Save

That’s it. I just need to insert markers into the target csproj file and run my template over it. Note that the merge parameter is slightly different as target type has changed to csproj: /merge:InsertRegion=”RegionName=Start;Language=csproj


Have fun using and extending merge functionality!

Leave a Reply