Thursday, 23 April 2009

Including up to date Generated Code in a Rebuild

I recently came up against a problem where I had a pre-build event in a Visual Studio project that generated some code that was to be included when that project was built. While the code files were generated successfully the generated assembly always seemed to use the files generated for the previous build.

Most of the time this was not an issue as the generated code stayed the same, but if I changed one of the files that the generator used as a source, or the generator code itself I had to hit Rebuild twice in order for the new code to be picked up. It was as if Visual Studio was checking what files or versions of files were to be included before running the pre-build event. I tried some remedies suggested on the internet, but none of them worked; I always had to click Rebuild twice.

I reasoned that if a pre-build event did not work, perhaps I could use a post-build event on another project in the solution, and copy the results to the project I wanted them in. That way the code would be generated before Visual Studio got it’s mucking hands on it.

To reproduce this solution:
  • Imagine the project you want the generated code to be compiled into is called RealProject
  • Create another project in your solution. I chose a class library and called it CodeGenerator, but you could use any project type I guess.
  • Put your generating code in the post-build event of the CodeGenerator project. My code was similar to the following:
    CodeGeneratingApp.exe parameter1 parameter2 > “$(SolutionDir)RealProject\GeneratedCode.cs
  • Build CodeGenerator
  • Highlight RealProject in the Solution Explorer and Click the show all files button.
  • Include GeneratedCode.cs in Real Project
  • Right click RealProject in Solution Explorer and choose Project Dependencies
  • Check the CodeGenerator project.
Now whenever you rebuild RealProject, CodeGenerator should also be rebuilt and the newly generated code will be compiled into RealProject.

I used this procedure to generate a set of WCF Data and Service contracts based on some LinqToSql classes in a project that I am in the VERY EARLY stages of developing on sourceforge. I did not want to use the LinqToSql classes directly in the contract, so that the client did not need to reference the data layer’s assembly. Here is a link to the project page.

No comments:

Post a Comment