It is widely known today that the ASP.NET runtime detects changes to the source ASPX files and invalidates the corresponding assemblies. This is written everywhere in the literature. Other, more advanced sources, arrive to the point of hinting at how this is accomplished: using the file notification mechanism that is built into Windows since Windows 95. In the .NET Framework, it is named FileSystemWatcher.
Have you ever realized that this information is incomplete?
The file system watcher is set up when the Web application is started, and a new instance of the HttpRuntime object is created in a new AppDomain. As long as the application is up and running, the file watcher monitors the source ASPX for a given page.
If the information above was the only thing to know (and do, if you want to emulate the feature), then if you stop the application, modify the ASPX, and resume, no changes should be detected because no watcher is running when you modify the page.
What's the missing link?
In the ASP.NET temporary folder (C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\Temporary ASP.NET Files) each visited ASPX page has an associated XML file. For example, default.aspx has a file like this:
default.xml.[hash code].xml
That XML file contains the name of the dynamically created page assembly, the type to load from the assembly, the list of dependencies for the page (the ASPX, linked DLLs, master pages in ASP.NET 2.0). In addition, this XML file has a hash attribute. I don't know exactly what info is hashed there and how. But I'm pretty sure that it contains the timestamps of all dependent files at the very least.
When the application starts up, and the page is invoked, if such XML file for the page exists the HTTP runtime reads the stored timestamp for the ASPX source file and if it doesn't match the current timestamp (i.e., the file was modified) the assembly is recreated and--conclusive and decisive proof--the XML file is updated!
OK. But what's the point?
I tried to implement a similar mechanism for a custom type of file and I realized that the FileSystemWatcher class can't guarantee that changes are detected if you operate them offline. Obvious, once you know it.
The great news is that the new compilation model in Whidbey will make this sort of (necessary) things much much easier.