MSBuild.aspx) is a very powerful build tool. Unfortunately, in my experience, I have seen it utilized very little. Instead, developers rely entirely on Visual Studio for the build, which is a mistake. I think there are a couple reasons for this:
- Modifying the build feels like you are mucking in the internals of Visual Studio
- There is no convention based approaches for how to handle custom bulid targets
Now, you could go the way of NAnt, and have complete independence from Visual Studio. I think this is a mistake as well. Visual Studio, while being a royal pain much of the time, is still a very very very powerful tool. I believe we should embrace it, while using MSBuild plus conventions to achieve ultimate flexibility.
It’s actually quite simple. Each assembly/project already has its own *.csproj file, which is in essence a partial MSBuild file. The problem is editing it is weird and scary at times, because it is auto-generated by Visual Studio.
Just add the following to any or all your csproj files.
<project> ... All the visual studio muck ... <import project="$(MSBuildProjectName).targets" condition="Exists('$(MSBuildProjectName).targets')"></import> </project>
Then add a file with that name. If your projects name is Reference.Web, then add a file named Reference.Web.targets and include it in the project. The content could contain something like the following.
<project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <itemgroup> <files include="$(SolutionDir)\configuration\$(Configuration)\$(AssemblyName).*.config"></files> <files include="$(SolutionDir)\configuration\$(Configuration)\Common.*"></files> </itemgroup> <target name="InstallConfiguration"> <copy sourcefiles="@(Files)" destinationfolder="$(OutputPath)"></copy> </target> <target dependsontargets="InstallConfiguration" name="AfterBuild"></target> </project>
The only gotcha is Visual Studio won’t automatically notice the build file changes, so you still have to relad the assembly after you make a build file change.
UPDATE - More robust Import statement
Even better would be a conditional import, and you should use the MSBuildProjectName property instead of AssemblyName.