Running ASP.NET websites from the GAC was always something I wanted to try out, because with 40 websites running exactly the same code there must be a better way to deploy them. So last week I tried it out and to my surprise it worked right away. Here’s how to do it with your own websites
Step 1: Sign the website assembly
Before you can place assemblies in the GAC you have to sign them. With websites this can be a bit more difficult to achieve. There’s just one requirement for this to be possible: Use the web application project type as the basis for your website.
When you use the web application project type you get an extra tab in the Properties of the project that says “Signing”. There you can provide a strong-name keyfile to sign the application. After that it’s a matter of doing a rebuild and you have strong named assemblies.
Step 2: Make a separate deployment structure
Since the website will be running from the GAC you will need a different deployment structure. I used the following structure which worked great:
- Application root
- Bin
- WebApp
I used a separate bin directory where I placed all the assemblies required by the application. From there they are deployed in the GAC. The WebApp contains all aspx pages, css files and other files required for ASP.NET, but not a bin directory.
This structure can be expanded to allow multiple copies of the webapp directory with a different web.config. It’s not the prettiest structure when you have 40 websites, but hey the application is 7 years old, so we can’t modify the internals that much, that we can run multiple websites with the same aspx files.
Step 3: Modify web.config
One of the trickier steps in the process is changing the web.config so that the assemblies required for compilation of the aspx pages can be found. One of the utilities that will come in handy here is the sn.exe utility.
The <compilation> section in web.config contains the assemblies required for the compilation of the aspx pages in the website. This is where all the assemblies from the web application should be registered. The section looks something like this:
<compilation debug="false"> <assemblies> <add assembly="MyAssembly, version=1.0.0, culture=neutral, publicKeyToken=null"/> </assemblies> </compilation>
For each assembly directly referenced by the application you should include an <add> construction in this section. All other assemblies that are dependencies of the assemblies directly referenced by the application should be available from the bin directory specified earlier, but can be omitted here.
While not required you can also extract all the prefixes for custom controls from the pages and place them in the configuration file. This will make the website more maintainable, because you don’t have the prefixes and assembly references for the controls all over the pages in the website. To register the prefixes in the web.config you should modify the web.config file so that the <pages> section looks like this:
<pages> <controls> <add tagPrefix="custom" namespace="MyNamespace" assembly="MyAssembly, version=1.0.0, culture=neutral, publicKeyToken=null"/> </controls> </pages>
Step 4: Registering the assemblies in the GAC
The last step to get the website working involves registering the assemblies in the global assembly cache. Lazy as I am I created a powershell script to make this a quick and easy task. The script looks like this:
ls -filter *.dll -recurse | %{ gacutil -i $_.FullName }
Conclusion
While not really straightforward at first this can make the life of website sysadmins a whole lot easier and save on deployment costs. Also using the control prefix registration in web.config will make the website better maintainable. All things considered I think that running from the GAC is a pretty cool feature of ASP.NET and recommend for scenarios where you have about 25 websites or more on one server.