Home   |   QuickStart Welcome   |   ASP.NET   |   Web Services   |   How Do I...?   
  |   I want my samples in...      

ASP.NET 2.0 Quickstart Tutorials

Application Structure

ASP.NET can be used to host multiple Web applications, each identified using a unique URL prefix within a Web site (where a Web site is represented on a Web server as a unique HostName/Port combination). For example, a single Microsoft Internet Information Services (IIS) Web server with two mapped IP addresses (one aliased to "www.msn.com" and the other to "intranet") and three logical sites (http://intranet, http://www.msn.com, http://www.msn.com port 81) could expose the following six ASP.NET applications.

Application URL Description
http://intranet "Root" application on intranet site.
http://www.msn.com "Root" application on www.msn.com site.
http://www.msn.com:81 "Root" application on www.msn.com port 81 site.
http://intranet/training "Training" application on intranet site.
http://intranet/hr "HR" application on intranet site.
http://intranet/hr/compensation/ "Compensation" application on intranet site.

Note: The URL for the compensation application mentioned in the table is rooted within the HR application URL namespace. However, this URL hierarchy notation does not imply that the compensation application is contained or nested within the HR application. Rather, each application maintains an independent set of configuration and class resolution properties; both are logical peer child sites of the intranet site.

Each ASP.NET Framework application exposed within a URL namespace is backed using a file system directory located on either a local or remote file share. Application directories are not required to be centrally located within a contiguous part of the file system; they can be scattered throughout a disk. For example, the ASP.NET applications mentioned previously could be located in the different directories listed in the following table.

Application URL Physical path
http://intranet c:\inetpub\wwwroot
http://www.msn.com c:\inetpub\msnroot
http://www.msn.com:81 d:\msnroot81
http://intranet/training d:\serverapps\trainingapp
http://intranet/hr \\hrweb\sillystuff\reviews
http://intranet/hr/compensation/ c:\inetpub\wwwroot\compensation

Resolving Class References to Assemblies

Assemblies are the unit of class deployment in the common language runtime. Developers writing .NET Framework classes using Visual Studio .NET version 7.0 will produce a new assembly with each Visual Studio project that they compile. Although it is possible to have an assembly span multiple portable executable (PE) files (several module DLLs), Visual Studio .NET will, by default, compile all assembly code into a single DLL (1 Visual Studio .NET project = 1 .NET Framework assembly = 1 physical DLL).

You can use an assembly on a computer by deploying it into an assembly cache. The assembly cache can be either global to a computer or local to a particular application. Only code intended to be shared across multiple applications should be placed in the global system assembly cache. Code specific to a particular application, such as most Web application logic, should be deployed in the application's local assembly cache. One advantage of deploying an assembly within an application's local assembly cache is that only code within that application can access it. (This is a nice feature for scenarios involving ISPs.) It also facilitates side-by-side versioning of the same application because classes are private to each application version instance.

An assembly can be deployed into an application's local assembly cache by simply copying, XCOPYing, or FTPing the appropriate files into a directory that has been marked as an "assembly cache location" for that particular application. No additional registration tool must be run once the appropriate files are copied, and no reboot is necessary. This eliminates some of the difficulties currently associated with deploying COM components within ASP applications (currently, an administrator must log on to the Web server locally and run Regsvr32.exe).

By default, an ASP.NET Framework application is automatically configured to use the \bin subdirectory, located immediately under the application root, as its local assembly cache. The \bin directory is also configured to deny any browser access so that a remote client cannot download and steal the code. The following example shows a possible directory layout for an ASP.NET application, where the \bin directory is immediately under the application root.
C:\inetpub\wwwroot
   Web.cfg
   Default.aspx

   \bin                  <= Application assembly cache directory
      MyPages.dll
      MyBizLogic.dll

   \order
      SubmitOrder.aspx
      OrderFailed.aspx

      \img
         HappyFace.gif

ASP.NET Framework application Startup and Class Resolution

ASP.NET Framework applications are lazily constructed the first time a client requests a URL resource from them. Each ASP.NET Framework application is launched within a unique application domain (AppDomain)--a new common language runtime construct that enables process hosts to provide extensive code, security, and configuration isolation at run time.

ASP.NET is responsible for manually creating an application domain when a new application is started. As part of this process, ASP.NET provides configuration settings for the common language runtime to use. These settings include:
  • The directory paths that make up the local assembly cache. (Note: It is the .NET Framework application domain isolation architecture that allows each application to maintain its own local assembly cache.)
  • The application's security restrictions (what the application can access on the system).
Because ASP.NET does not have compile-time knowledge of any applications you write on top of it, it cannot use static references to resolve and reference application code. Instead, ASP.NET must use a dynamic class/assembly resolution approach to make the transition from the ASP.NET runtime into application code.

ASP.NET configuration and page activation files will enable you to dynamically reference a target-compiled .NET Framework class by specifying an assembly and class name combination. The string format for this union follows the pattern classname, assemblyname. The common language runtime can then use this simple string reference to resolve and load the appropriate class.

Code Replacement

.NET Framework assemblies are typically compiled and deployed into a Windows DLL-based PE format. When the common language runtime's loader resolves a class implemented within this type of assembly, it calls the Windows LoadLibrary routine on the file (which locks its access on disk), and then maps the appropriate code data into memory for run-time execution. Once loaded, the DLL file will remain locked on disk until the application domain referencing it is either torn down or manually recycled.

Although ASP.NET cannot prevent the common language runtime from locking a loaded assembly DLL on disk, it can support you by ensuring that the physical DLLs in a Web application's private assembly cache are never actually loaded by the runtime. Instead, shadow copies of the assembly DLLs are made immediately prior to their use. These shadow assemblies--not the original files--are then locked and loaded by the runtime.

Because the original assembly files always remain unlocked, you are free to delete, replace, or rename them without cycling the Web server or having to use a registration utility. FTP and similar methods work just fine. ASP.NET maintains an active list of all assemblies loaded within a particular application's application domain and uses file-change monitoring code to watch for any updates to the original files.