Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 185 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
185
Dung lượng
2,18 MB
Nội dung
Chapter 17: Assemblies 495 PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=msil ehepg, Version=6.0.6000.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=msil ehepgdat, Version=6.0.6000.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=msil ehExtCOM, Version=6.0.6000.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=msil ehexthost, Version=6.0.6000.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=msil ehRecObj, Version=6.0.6000.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=msil ehshell, Version=6.0.6000.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=msil EventViewer, Version=6.0.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=msil If the security of the system changes, it ’ s not sure if the native image has the security requirements it needs for running the application. This is why the native images become invalid with a system configuration change. With the command ngen update all native images are rebuilt to include the new configurations. Installing CLR 2.0 runtime also installs the Native Image Service (or the Window Service CLR Optimization Service), with the name Microsoft .NET Framework NGEN v2.0.50727_X86. This service can be used to defer compilation of native images and regenerates native images that have been invalidated. The command ngen install myassembly /queue can be used by an installation program to defer compilation of myassembly to a native image using the Native Image Service. ngen update /queue regenerates all native images that have been invalidated. With the ngen queue options pause , continue , and status you can control the service and get status information. You might ask why the native images cannot be created on the developer system, and you just distribute the native image to the production system. The reason is that the native image generator takes care of the CPU that is installed with the target system and compiles the code optimized for the CPU type. During installation of the application, the CPU is known. Configuring .NET Applications COM components used the registry to configure components. Configuration of .NET applications is done by using configuration files. With registry configurations, an xcopy deployment is not possible. Configuration files can simply be copied. The configuration files use XML syntax to specify startup and runtime settings for applications. This section explores the following: What you can configure using the XML base configuration files How you can redirect a strong named referenced assembly to a different version How you can specify the directory of assemblies to find private assemblies in subdirectories and shared assemblies in common directories or on a server ❑ ❑ ❑ c17.indd 495c17.indd 495 2/19/08 5:14:35 PM2/19/08 5:14:35 PM Part III: Base Class Libraries 496 Configuration Categories The configuration can be grouped into these categories: Startup settings enable you to specify the version of the required runtime. It ’ s possible that different versions of the runtime could be installed on the same system. The version of the runtime can be specified with the < startup > element. Runtime settings enable you to specify how garbage collection is performed by the runtime, and how the binding to assemblies works. You can also specify the version policy and the code base with these settings. You take a more detailed look into the runtime settings later in this chapter. WCF settings are used to configure applications using WCF. You deal with these configurations in Chapter 42 , “ Windows Communication Foundation. ” Security settings are introduced in Chapter 20 , “ Security, ” and configuration for cryptography and permissions is done there. These settings can be provided in three types of configuration files: Application configuration files include specific settings for an application, such as binding information to assemblies, configuration for remote objects, and so on. Such a configuration file is placed into the same directory as the executable; it has the same name as the executable with a .config extension appended. ASP.NET configuration files are named web.config . Machine configuration files are used for system - wide configurations. You can also specify assembly binding and remoting configurations here. During a binding process, the machine configuration file is consulted before the application configuration file. The application configuration can override settings from the machine configuration. The application configuration file should be the preferred place for application - specific settings so that the machine configuration file stays smaller and more manageable. A machine configuration file is located in %runtime_install_path%\config\ Machine.config . Publisher policy files can be used by a component creator to specify that a shared assembly is compatible with older versions. If a new assembly version just fixes a bug of a shared component, it is not necessary to put application configuration files in every application directory that uses this component; the publisher can mark it as compatible by adding a publisher policy file instead. In case the component doesn ’ t work with all applications, it is possible to override the publisher policy setting in an application configuration file. In contrast to the other configuration files, publisher policy files are stored in the GAC. How are these configuration files used? How a client finds an assembly (also called binding ) depends on whether the assembly is private or shared. Private assemblies must be in the directory of the application or in a subdirectory thereof. A process called probing is used to find such an assembly. If the assembly doesn ’ t have a strong name, the version number is not used with probing. Shared assemblies can be installed in the GAC or placed in a directory, on a network share, or on a Web site. You specify such a directory with the configuration of the codeBase shortly. The public key, version, and culture are all important aspects when binding to a shared assembly. The reference of the required assembly is recorded in the manifest of the client assembly, including the name, the version, and the public key token. All configuration files are checked to apply the correct version policy. The GAC and code bases specified in the configuration files are checked, followed by the application directories, and probing rules are then applied. ❑ ❑ ❑ ❑ ❑ ❑ ❑ c17.indd 496c17.indd 496 2/19/08 5:14:35 PM2/19/08 5:14:35 PM Chapter 17: Assemblies 497 Configuring Directories for Assembly Searches You ’ ve already seen how to install a shared assembly to the GAC. Instead of installing a shared assembly to the GAC, you can configure a specific shared directory by using configuration files. This feature can be used if you want to make the shared components available on a server. Another possible scenario arises if you want to share an assembly between your applications, but you don ’ t want to make it publicly available in the GAC, so you put it into a shared directory instead. There are two ways to find the correct directory for an assembly: the codeBase element in an XML configuration file, or through probing. The codeBase configuration is available only for shared assemblies, and probing is done for private assemblies. < codeBase > The < codeBase > can also be configured using the .NET Configuration utility. Code bases can be configured by selecting the properties of the configured application, SimpleShared , inside the Configured Assemblies in the Applications tree. Similarly to the Binding Policy, you can configure lists of versions with the Codebases tab. Figure 17 - 17 shows that the version 1.1 should be loaded from the Web server http://www.christiannagel.com/WroxUtils . Figure 17 - 17 The .NET Configuration utility creates this application configuration file: < ?xml version=”1.0”? > < configuration > < runtime > < assemblyBinding xmlns=”urn:schemas-microsoft-com:asm.v1” > < dependentAssembly xmlns=”” > < assemblyIdentity name=”SimpleShared” publicKeyToken=”7d886a6f7b9f0292” / > < codeBase version=”1.1” href=”http://www.christiannagel.com/WroxUtils” / > (continued) c17.indd 497c17.indd 497 2/19/08 5:14:36 PM2/19/08 5:14:36 PM Part III: Base Class Libraries 498 < /dependentAssembly > < /assemblyBinding > < /runtime > < /configuration > The < codeBase > element has the attributes version and href . With version , the original referenced version of the assembly must be specified. With href , you can define the directory from where the assembly should be loaded. In the example, a path using the HTTP protocol is used. A directory on a local system or a share is specified using href= “ file:C:/WroxUtils ” . Using that assembly loaded from the network causes a System.Security.Permissions exception to occur. You must configure the required permissions for assemblies loaded from the network. In Chapter 20 , “ Security, ” you learn how to configure security for assemblies. < probing > When the < codeBase > is not configured and the assembly is not stored in the GAC, the runtime tries to find an assembly through probing. The .NET runtime tries to find assemblies with either a .dll or an .exe file extension in the application directory, or in one of its subdirectories, that has the same name as the assembly searched for. If the assembly is not found here, the search continues. You can configure search directories with the < probing > element in the < runtime > section of application configuration files. This XML configuration can also be done easily by selecting the properties of the application with the .NET Framework Configuration tool. You can configure the directories where the probing should occur by using the search path in the .NET Framework configuration (see Figure 17 - 18 ). Figure 17 - 18 (continued) The XML file produced has these entries: < ?xml version=”1.0”? > < configuration > < runtime > < gcConcurrent enabled=”true” / > < assemblyBinding xmlns=”urn:schemas-microsoft-com:asm.v1” > c17.indd 498c17.indd 498 2/19/08 5:14:36 PM2/19/08 5:14:36 PM Chapter 17: Assemblies 499 < probing privatePath=”bin;utils;” xmlns=”” / > < /assemblyBinding > < /runtime > < /configuration > The < probing > element has just a single required attribute: privatePath . This application configuration file tells the runtime that assemblies should be searched for in the base directory of the application, followed by the bin and the util directory. Both directories are subdirectories of the application base directory. It ’ s not possible to reference a private assembly outside the application base directory or a subdirectory thereof. An assembly outside of the application base directory must have a shared name and can be referenced using the < codeBase > element, as you saw earlier. Versioning For private assemblies, versioning is not important because the referenced assemblies are copied with the client. The client uses the assembly it has in its private directories. This is, however, different for shared assemblies. This section looks at the traditional problems that can occur with sharing. With shared components, more than one client application can use the same component. The new version can break existing clients when updating a shared component with a newer version. You can ’ t stop shipping new versions because new features are requested and introduced with new versions of existing components. You can try to program carefully to be backward compatible, but that ’ s not always possible. A solution to this dilemma could be an architecture that allows installation of different versions of shared components, with clients using the version that they referenced during the build process. This solves a lot of problems but not all of them. What happens if you detect a bug in a component that ’ s referenced from the client? You would like to update this component and make sure that the client uses the new version instead of the version that was referenced during the build process. Therefore, depending on the type in the fix of the new version, you sometimes want to use a newer version, and you also want to use the older referenced version as well. The .NET architecture enables both scenarios. In .NET, the original referenced assembly is used by default. You can redirect the reference to a different version using configuration files. Versioning plays a key role in the binding architecture — how the client gets the right assembly where the components live. Version Numbers Assemblies have a four - part version number, for example, 1.1.400.3300 . The parts are < Major > . < Minor > . < Build > . < Revision > . How these numbers are used depends on your application configuration. A good policy is to change the major or minor number on changes incompatible with the previous version, but just the build or revision number with compatible changes. This way, it can be assumed that redirecting an assembly to a new version where just the build and revision changed is safe. With Visual Studio 2008, you can define the version number of the assembly with the assembly information in the project settings. The project settings write the assembly attribute [AssemblyVersion] to the file AssemblyInfo.cs : [assembly: AssemblyVersion(“1.0.0.0”)] c17.indd 499c17.indd 499 2/19/08 5:14:36 PM2/19/08 5:14:36 PM Part III: Base Class Libraries 500 Instead of defining all four version numbers you can also place an asterisk in the third or fourth place: [assembly: AssemblyVersion(“1.0.*”)] With this setting, the first two numbers specify the major and minor version, and the asterisk ( * ) means that the build and revision numbers are auto - generated. The build number is the number of days since January 1, 2000, and the revision is the number of seconds since midnight divided by two. Though the automatic versioning might help during development time, before shipping it is a good practice to define a specific version number. This version is stored in the .assembly section of the manifest. Referencing the assembly in the client application stores the version of the referenced assembly in the manifest of the client application. Getting the Version Programmatically To make it possible to check the version of the assembly that is used from the client application, add the method GetAssemblyFullName() to the SharedDemo class created earlier to return the strong name of the assembly. For easy use of the Assembly class, you have to import the System.Reflection namespace: public string GetAssemblyFullName() { return Assembly.GetExecutingAssembly().FullName; } The FullName property of the Assembly class holds the name of the class, the version, the locality, and the public key token, as you see in the following output, when calling GetAssemblyFullName() in your client application. In the client application, just add a call to GetAssemblyFullName() in the Main() method after creating the shared component: static void Main() { SharedDemo quotes = new SharedDemo(@”C:\ProCSharp\Assemblies\Quotes.txt”); Console.WriteLine(quotes.GetAssemblyFullName()); Be sure to register the new version of the shared assembly SharedDemo again in the GAC using gacutil . If the referenced version cannot be found, you will get a System.IO.FileLoadException , because the binding to the correct assembly failed. With a successful run, you can see the full name of the referenced assembly: SharedDemo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7d886a6f7b9f0292 Press any key to continue This client program can now be used to test different configurations of this shared component. Application Configuration Files With a configuration file, you can specify that the binding should happen to a different version of a shared assembly. Assume that you create a new version of the shared assembly SharedDemo with major and minor versions 1.1. Maybe you don ’ t want to rebuild the client but just want the new version of the assembly to be used with the existing client instead. This is useful in cases where either a bug is fixed with the shared assembly or you just want to get rid of the old version because the new version is compatible. c17.indd 500c17.indd 500 2/19/08 5:14:37 PM2/19/08 5:14:37 PM Chapter 17: Assemblies 501 Figure 17 - 19 shows the Global Assembly Cache Viewer, where the versions 1.0.0.0 and 1.0.3300.0 are installed for the SharedDemo assembly. Figure 17 - 19 Figure 17 - 20 shows the manifest of the client application where the client references version 1.0.0.0 of the assembly SharedDemo . Figure 17 - 20 Now an application configuration file is needed. It is not necessary to work directly with XML; the .NET Framework Configuration tool can create application and machine configuration files. Figure 17 - 21 shows the .NET Framework Configuration tool, which is an MMC Snap - in. You can start this tool from Administrative Tools in the Control Panel. This tool is shipped with Framework SDK and not with the .NET runtime, so don ’ t expect this tool to be available to system administrators. c17.indd 501c17.indd 501 2/19/08 5:14:37 PM2/19/08 5:14:37 PM Part III: Base Class Libraries 502 Select Configured Assemblies in the tree view and the menu Action Add . . . to configure the dependency of the assembly SharedDemo from the dependency list. Select the Binding Policy tab to define the version that should be used as shown in Figure 17 - 23 . Figure 17 - 21 When you select Applications on the left side, and then select Action Add, you can choose a .NET application to configure. If the Client.exe application does not show up with the list, click the Other . . . button and browse to the executable. Select the application Client.exe to create an application configuration file for this application. After adding the client application to the .NET Configuration utility, the assembly dependencies can be listed, as shown in Figure 17 - 22 . Figure 17 - 22 c17.indd 502c17.indd 502 2/19/08 5:14:37 PM2/19/08 5:14:37 PM Chapter 17: Assemblies 503 Figure 17 - 23 For the requested version, specify the version referenced in the manifest of the client assembly. newVersion specifies the new version of the shared assembly. In Figure 17 - 23 , it is specified that the version 1.0.3300.0 should be used instead of any version in the range of 1.0.0.0 to 1.0.3300.0. Now you can find the application configuration file Client.exe.config in the directory of the Client.exe application that includes this XML code: < ?xml version=”1.0”? > < configuration > < runtime > < assemblyBinding xmlns=”urn:schemas-microsoft-com:asm.v1” > < dependentAssembly > < assemblyIdentity name=”SharedDemo” publicKeyToken=”7d886a6f7b9f0292” / > < publisherPolicy apply=”yes” / > < bindingRedirect oldVersion=”1.0.0.0-1.0.3300.0” newVersion=”1.0.3300.0” / > < /dependentAssembly > < /assemblyBinding > < /runtime > < /configuration > Runtime settings can be configured with the < runtime > element. The subelement of < runtime > is < assemblyBinding > , which in turn has a subelement < dependentAssembly > . < dependentAssembly > has a required subelement < assemblyIdentity > . You specify the name of the referenced assembly with < assemblyIdentity > . name is the only mandatory attribute for < assemblyIdentity > . The optional attributes are publicKeyToken and culture . The other subelement of < dependentAssembly > that ’ s needed for version redirection is < bindingRedirect > . The old and the new versions of the dependent assembly are specified with this element. When you start the client with this configuration file, you will get the new version of the referenced shared assembly. c17.indd 503c17.indd 503 2/19/08 5:14:38 PM2/19/08 5:14:38 PM Part III: Base Class Libraries 504 Publisher Policy Files Using assemblies shared from the GAC allows you to use publisher policies to override versioning issues. Assume that you have an assembly used by some applications. What can be done if a critical bug is found in the shared assembly? You have seen that it is not necessary to rebuild all the applications that use this shared assembly, because you can use configuration files to redirect to the new version of this shared assembly. Maybe you don ’ t know all the applications that use this shared assembly, but you want to get the bug fix to all of them. In that case, you can create publisher policy files to redirect all applications to the new version of the shared assembly. Publisher policy files apply only to shared assemblies installed in the GAC. To set up publisher policies, you have to do the following: Create a publisher policy file Create a publisher policy assembly Add the publisher policy assembly to the GAC Create a Publisher Policy File A publisher policy file is an XML file that redirects an existing version or version range to a new version. The syntax used here is the same as for application configuration files, so you can use the same file you created earlier to redirect the old versions 1.0.0.0 through 1.0.3300.0 to the new version 1.0.3300.0. Rename the previously created file to mypolicy.config to use it as a publisher policy file and remove the element < publisherPolicy > : < ?xml version=”1.0”? > < configuration > < runtime > < assemblyBinding xmlns=”urn:schemas-microsoft-com:asm.v1” > < dependentAssembly > < assemblyIdentity name=”SharedDemo” publicKeyToken=”7d886a6f7b9f0292” / > < bindingRedirect oldVersion=”1.0.0.0-1.0.3300.0” newVersion=”1.0.3300.0” / > < /dependentAssembly > < /assemblyBinding > < /runtime > < /configuration > Create a Publisher Policy Assembly To associate the publisher policy file with the shared assembly, it is necessary to create a publisher policy assembly, and to put it into the GAC. The tool that can be used to create such files is the assembly linker al . The option /linkresource adds the publisher policy file to the generated assembly. The name of the generated assembly must start with policy, followed by the major and minor version number of the assembly that should be redirected, and the file name of the shared assembly. In this case the publisher policy assembly must be named policy.1.0.SharedDemo.dll to redirect the assemblies SharedDemo with the major version 1 and minor version 0. The key that must be added to this publisher key with the option /keyfile is the same key that was used to sign the shared assembly SharedDemo to guarantee that the version redirection is from the same publisher. ❑ ❑ ❑ c17.indd 504c17.indd 504 2/19/08 5:14:38 PM2/19/08 5:14:38 PM [...]... creating assemblies during runtime If you want to get more information on this, you should read Chapter 36 about the Add-In model of NET 3.5 507 c17.indd 507 2/19/08 5: 14: 39 PM c17.indd 508 2/19/08 5: 14: 39 PM Tracing and Events Chapter 14 covered errors and exception handling Besides handling exceptional code, it might be really interesting to get some live information about your running application to... the listeners of the trace source: . in common directories or on a server ❑ ❑ ❑ c17.indd 49 5c17.indd 49 5 2/19/08 5: 14: 35 PM2/19/08 5: 14: 35 PM Part III: Base Class Libraries 49 6 Configuration Categories The configuration can. and probing rules are then applied. ❑ ❑ ❑ ❑ ❑ ❑ ❑ c17.indd 49 6c17.indd 49 6 2/19/08 5: 14: 35 PM2/19/08 5: 14: 35 PM Chapter 17: Assemblies 49 7 Configuring Directories for Assembly Searches You. href=”http://www.christiannagel.com/WroxUtils” / > (continued) c17.indd 49 7c17.indd 49 7 2/19/08 5: 14: 36 PM2/19/08 5: 14: 36 PM Part III: Base Class Libraries 49 8 < /dependentAssembly > < /assemblyBinding