Deploying an Assembly

In the past, the use of component-based development with distributed applications was plagued by constant deployment headaches. If you wanted to access Microsoft's rich set of COM+ services and create objects that were easy to reuse in any language, you had to write COM components, which had to be registered on multiple computers. If you tried another approach (such as creating your own low-level DLLs), you escaped the registration problem but were left out in the cold without easy reuse, versioning, or the ability to use distributed application essentials such as connection pooling.

In .NET, the deployment picture has improved considerably. After you've created a component and referenced it in a project, you just need to distribute the project and component assembly together. For a typical Windows application, that means copying the project executable along with the DLL assembly to the same directory on the server. When the client launches the application, it will find and use the required assembly painlessly. The Windows Registry doesn't play any role at all. In an ASP.NET application, the process is similar, except you deploy ASP.NET pages to a virtual directory on a Web server and any required assemblies to a Bin subdirectory of the virtual directory. Once again, the .NET Framework finds the required assembly automatically; reads all the metadata it needs about available classes, methods, events, and properties; and allows the client code to interact with it just as easily as if the class were a part of the Web page code. This process flows equally smoothly if the component is written in another language supported by .NET.

The only requirement is that the client computer have the .NET Framework installed. To install the .NET Framework, you can use the standard .NET redistributable (available for download from Microsoft and included with Visual Studio .NET). This redistributable supports the following operating systems:

  • Windows 98

  • Windows 98 Second Edition

  • Windows Millennium Edition (Windows Me)

  • Windows NT 4.0 (Workstation or Server) with Service Pack 6a

  • Windows 2000 (Professional, Server, or Advanced Server)

  • Windows XP (Home or Professional)

  • Windows .NET Server

  • Windows Server 2003

Internet Explorer 5.0 and Windows Installer 2.0 are also required. Keep in mind that these requirements apply to any clients that want to execute .NET code. If you're creating a Java client that talks to a .NET Web service or using an ASP.NET Web site that users can access through an ordinary browser, these requirements obviously don't apply.

Sharing Assemblies

Every experienced developer who learns about .NET's painless new deployment system has two questions:

  • How do I update an assembly without breaking an application?

  • How do I share an assembly between applications?

The answers to these questions depend on whether you're using private or shared assemblies. Shared assemblies are made globally available to every .NET application on the computer. Private assemblies are constrained to applications that know how to find them.

At this point, you're probably quietly concluding that you need to create shared assemblies to reuse important core pieces of functionality. Not so fast. There are some serious potential headaches that you probably haven't considered:

  • Shared assemblies need a strong name, which guarantees that they won't conflict with any other component in the global assembly cache (GAC). To create this strong name, you have to sign the assembly with a public/private key pair.

  • Like COM components, the GAC is computer-specific. This means you must install the component in the cache of the same computer that will run the client application. If you want to use a component with different instances of a Windows application, for example, you need to install the assembly on each and every client machine. Other­wise, when the client runs the application, the required component assembly won't be found.

The second problem is by far the most significant. Even if you're creating a component that you want to execute in the process space of another computer, the client still needs to be able to reference it. Otherwise, it won't have the information it needs about properties, methods, and events. For these reasons, it might make little sense to place a component in the computer-specific registry such as the GAC, especially if it needs to be used by applications running on several different machines. In this case, .NET's capability to load an assembly directly from an unregistered file is far superior.

So how can you share a private component among multiple applications in different directories? Well, one option would be to place a separate copy of the component into every application directory. This actually isn't such a bad idea. That way, you could theoretically update some applications with a new version of the component while ensuring that other applications use the original version. It's also incredibly easy. Unfortunately, you can't overwrite the assembly while it's in use, which presents one possible problem. (ASP.NET is one pleasant exception because it enables you to update private assemblies even when they are in use.) This system is also likely to lead to some level of disorder if you need to reuse a basic component with a large number of different applications. To implement a more consistent approach, you need to use a custom configuration file.

Searching for Private Assemblies

By default, .NET automatically searches the root directory of the application for any referenced assemblies. However, you can also instruct .NET to consider other locations. To do so, you need to create an application configuration file. As described earlier in this chapter, every configuration file has the same name as the .NET assembly, plus the extension .config (as in myapp.exe.config). If this file exists in the same directory, .NET reads and applies its settings automatically. The exception is with ASP.NET configuration files, which always use the fixed name web.config.

The CodeBase Element

The configuration file uses a simple XML-based format. Listing 2-4 is a sample configuration that specifically indicates that the private assembly DBComponent.dll is located in the subdirectory Components.

Listing 2-4 A sample configuration file
 <?xml version="1.0"?> <configuration>   <runtime>     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">       <dependentAssembly>         <assemblyIdentity name="DBComponent" />         <codeBase href="Components\DBComponent.dll" />       </dependentAssembly>     </assemblyBinding>   </runtime> </configuration> 

You can provide explicit directory information for multiple assemblies in this fashion by adding additional <dependent> assembly elements:

 <?xml version="1.0"?> <configuration>   <runtime>     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">       <dependentAssembly>         <assemblyIdentity name="DBComponent" />         <codeBase href="Components\DBComponent.dll" />       </dependentAssembly>       <dependentAssembly>         <assemblyIdentity name="LogComponent" />         <codeBase href="Log\LogComponent.dll" />       </dependentAssembly>     </assemblyBinding>   </runtime> </configuration> 

In this case, if the LogComponent or DBComponent assemblies reference other private assemblies, .NET will automatically search in the corresponding Components or Log directory. This makes it easy to distribute a group of related components without having to write too much information in the configuration file.

The Probing Element

Alternatively, you can use the <probing> element, which is far less invasive than it sounds. Probing is the process by which .NET searches for private assemblies that aren't specifically configured. By default, it tries these two locations:

 AppPath\[Assembly Name].dll AppPath\[Assembly Name]\[Assembly Name].dll 

If you have specified culture information for the referenced assembly, it performs a similar lookup attempt but automatically searches in the culture-specific subdirectory rather than the application path.

You can configure this probing process to use other directories by adding the probing element to the configuration file. This element specifies valid subdirectories to search for any private assembly that can't be located, separated by semicolons. The following example searches both the Components and Log subdirectories:

 <configuration>    <runtime>       <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">          <probing privatePath="Components;Log"/>       </assemblyBinding>    </runtime> </configuration> 

The only limitation with code bases and probing is that they must point to a subdirectory of the application directory. Unfortunately, they can't point to a directory higher up the tree or to a directory on another drive.



Microsoft. NET Distributed Applications(c) Integrating XML Web Services and. NET Remoting
MicrosoftВ® .NET Distributed Applications: Integrating XML Web Services and .NET Remoting (Pro-Developer)
ISBN: 0735619336
EAN: 2147483647
Year: 2005
Pages: 174

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net