Wednesday, June 06, 2007

Shadow Copying

A fantastic feature of ASP.NET is that the code for a Web site can be changed on the fly without shutting down the Web server. When a Web site's file is changed on the hard disk, ASP.NET detects this, unloads the AppDomain that contains the old version of the files (when the last currently running request finishes), and then creates a new AppDomain, loading into it the new versions of the files. To make this happen, ASP.NET uses an AppDomain feature called
shadow copying.

Shadow Copying Assemblies

Shadow copying allows assemblies that are used in an application domain to be updated without unloading the application domain. This is particularly useful for applications that must be available continuously, such as ASP.NET sites.

The common language runtime locks an assembly file when the assembly is loaded, so the file cannot be updated until the assembly is unloaded. The only way to unload an assembly from an application domain is by unloading the application domain, so under normal circumstances, an assembly cannot be updated on disk until all the application domains that are using it have been unloaded.

When an application domain is configured to shadow copy files, assemblies from the application path are copied to another location and loaded from that location. The copy is locked, but the original assembly file is unlocked and can be updated.

The following list describes how to use the properties of the AppDomainSetup class to configure an application domain for shadow copying.

  • Enable shadow copying by setting the ShadowCopyFiles property to the string value "true".

    By default, this causes all assemblies in the application path to be copied to a download cache before they are loaded. This is the same cache maintained by the common language runtime to store files downloaded from other computers, and the common language runtime automatically deletes the files when they are no longer needed.

A little example

Let's come to the point. How to enable this kind of stuff in your own application? A really simple and short example:

First, write a method to create a new app domain to host the new version of the assembly. As you might know, it's impossible to unload an assembly once loaded in an appdomain, you can only unload the associated appdomain entirely. What the following method does is pretty straightforward: it tells the CLR (assembly loader) where to look for files and then tells it to enable shadow copying by setting the (wrong-typed; a boolean property would have been much better) ShadowCopyFiles property to the string "true". Next, an appdomain is created with a unique name using some counter, and the assembly with the functionality is loaded (notice the _ indicates private members of the current class). This method is called when the app starts.

private void LoadAppDomain()
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = "c:\\temp";
setup.ShadowCopyFiles = "true";
AppDomain domain = AppDomain.CreateDomain("ShadowCopy
domain " + _domainNumber, null, setup);
_currentAssembly = domain.Load("Server", null);

1 comment:

Anonymous said...

Don't you have any shame? Blatantly copying other people's work can land your ass in jail in some countries even if it is just paragraphs. At least have the decency to make write up in your own words and put a reference in your text!