Deploying Web applications was once one of the most tedious and difficult parts of ASP development. You had to configure the application settings "in person" at the server, and had to register components manually (using REGSVR32.exe) or via Microsoft Transaction Server. This often introduced many versioning problems, such as DLL hell, in which conflicting library versions would cause the application to function improperly, or not to function at all.
With ASP.NET, all that is required to deploy applications is simply to copy the needed files (ASP.NET Web pages, the web.config file, and necessary DLLs) to the deployment Web server no more registering components or tweaking Web server settings! Let's take a deeper look at this marvelous mechanism.
Recall from Day 2, "Building ASP.NET Pages," that assemblies are the basic unit of sharing and reuse in the Common Language Runtime a named unit for class deployment. Typically an assembly is a single DLL file, but may span multiple files (and even file types).
Assemblies are used by ASP.NET applications by placing them into either a global or local assembly cache. Global caches hold code that is accessed by all applications on an ASP.NET server. This cache, by default, is located in your \WinNT\Assembly directory.
You can use the global cache utility (gacutil.exe) from the command line to view, add, and remove assemblies from the global cache. The syntax is
Usage: Gacutil <option> [<parameters>] Options: -i Installs an assembly to the global assembly cache. Include the name of the file containing the manifest as a parameter. Example: -i myDll.dll -u Uninstalls an assembly from the global assembly cache. Include the name of the assembly to remove as a parameter. Examples:. -u myDll -u myDll,Ver=184.108.40.206,Loc=en,PK=874e23ab874e23ab -l Lists the contents of the global assembly cache -? Displays this help screen
Beware, though, that specifying gacutil u myDLL will remove all versions of myDLL, so be sure to specify as much information as necessary.
Local caches are accessible only by a particular application; the default cache is the /bin subdirectory in your application root. This directory is configured to deny access to any client requests a helpful feature so that no one can steal your code. Let's take a look at a sample Web server directory structure as shown in Table 18.3.
Table 18.3. A Sample Web Server Directory Structure
|Application URL ||Physical Path |
|http://www.site.com ||c:\inetpub\wwwroot |
|http://www.site.com:85 ||c:\inetpub\wwwroot\port85 |
|http://www.site.com/games ||d:\www\games |
|http://www.site.com/games/users ||d:\www\users |
Each of the physical directories in Table 18.3 is a virtual directory in IIS and a separate ASP.NET application. Each application can have its own local assembly cache in its /bin subdirectory; c:\inetpub\wwwroot\bin for www.site.com, for instance. Each /bin directory is applicable only to its local application. This allows you to deploy multiple versions of the same assembly on one site!
Typically, when the CLR loads an assembly DLL into memory, it locks access to the file so that no other applications can access or corrupt it. The file is unlocked when the application domain referencing it is destroyed. This is great to ensure stability, but it results in high costs to replace those files. For example, with traditional ASP, these DLLs would remain locked until the server was restarted a pain for administrators and site visitors.
ASP.NET solves this problem by not loading the actual assemblies into memory. Instead, shadow copies of the assemblies are created immediately before their use, and it is these that are locked and loaded into memory. Because the actual files are no longer locked, developers are free to replace them as they want no restarts are necessary.
ASP.NET monitors and detects any changes to the actual files. If it discovers that the file has changed, it creates a shadow copy of the new file, loads it into memory, and gradually siphons off requests from the old version. After all requests reference the new version, the old version is destroyed. This is largely transparent to the end user. How's that for saving headaches!