Rick Strahl presents a GUI utility to drive the aspnet_compiler command line tool, and voices valid criticisms of ASP.NET 2.0 deployment options with “ASP.NET 2.0 Application Deployment in the real world”.
Is pre-compilation for deployment worth the trouble? The performance advantages to pre-compilation are almost insignificant. Pre-compilation is not NGEN. There remains a hefty amount of JIT compiling at startup, not to mention warming up the cache, establishing connections … the to-do list for the runtime at startup goes on and on.
There are, however, at least two good reasons to pre-compile. First, pre-compilation will find any syntactical errors that might be lurking inside in the application. Even if you don’t deploy a pre-compiled version of an application, pre-compilation should be a part of every build process to ensure there are no errors.
A second reason, good for shared hosting environments, is that pre-compilation will lock down the application. You can deploy an ASP.NET application without deploying any source code whatsoever (not even ASPX files). No one can change your application, or even place a new ASPX file inside your directory in a hack attempt (the new page will throw an exception if executed). Note: you can pre-compile ‘for update’ if you still need dynamic compilation of aspx, ascx files, like for applications that use skins.
A drawback to pre-compilation that Rick points out is the lack of control you have over the /bin directory. Every folder with a web form inside will compile into a different .dll. In addition, the compiler generates part of the assembly’s name at random. The first time you precompile, you might see App_Web_vifortkl.dll appear. The second time, the same directory will produce an App_Web_snarkfob.dll assembly. Multiple XCOPY deployments with no clean up will result in a /bin directory littered with obsolete dlls.
The solution to this problem is to pass –fixednames as a parameter to the aspnet_compiler. The fixednames parameter will force the compiler to generate the same filename on each pre-compilation run for an application, but there is a catch. Each web form and user control will produce an individual assembly! If you have 5 web forms, you’ll find at least 5 assemblies in the bin. Actually, there will be 10 files total, because alongside each .dll file is a .compiled file filled with XML to map source files to assemblies.
You might also use the –d switch to place debugging information for each assembly into a pdb file. PDBs are essential if you want to see line numbers in a production exception’s stack trace. Now there are three files per form. I pre-compiled one of the smallest applications I have with –d –fixednames, an application with only 12 web forms and some user controls, and found 21 assemblies in /bin. 63 total files!
Each assembly adds a little overhead to the working set of an application. I’m interested to see the impact on large applications where the number of assemblies reaches into the hundreds.
Each assembly also adds some overhead in getting files to a production server. If you are FTP-ing all these files to a shared host with the application online, remember each write to the /bin directory will put your application into a state of flux until all the files are complete.
The underlying problem isn’t performance worries or deployment overhead, but loss of control over the build outputs of an ASP.NET application. At first glance it would seem easy to map each directory and file name into a namespace and type name, then put all forms and controls into a single assembly, but then many problems seem easy at first glance.
I’m hoping the uneasy feeling I get when looking in a /bin directory goes away.