Section 5.6. CLR Versioning


5.6. CLR Versioning

.NET's rigorous enforcement of version compatibility raises an interesting problem: if an application is built against version 2.0 of .NET, when version 3.0 of .NET becomes available, the application will not be able to take advantage of it. The reason is that the application's manifest contains the version numbers of all the assemblies it relies on, including the CLR and application frameworks. The .NET assemblies are strongly named, and therefore the assembly resolver will insist on a perfect version match.

To overcome the issue of version compatibility with its own assemblies, .NET provides a different set of ground rules. The issues involved are intricate. The exact version of the CLR used by the components in a class library or an EXE may vary, and it depends on what they were compiled with, the available .NET versions, and the application versioning policy.

The .NET architects tried to strike a balance between allowing innovation and new versions on the one hand, and supporting existing applications on the other. Ultimately, it's up to the application vendor to decide whether to support a particular CLR version. This marks a change of philosophy: Microsoft no longer guarantees absolute backward and forward compatibility. Instead, Microsoft pledges to make every effort to be backward-compatible and to point out where there are incompatibilities. That, of course, does not mean that a new .NET version will be fully backward-compatible; all it means is that in the places that it is not backward-compatible, this was not done deliberately. The one exception to that pledge is securityMicrosoft will knowingly make breaking changes in newer versions of .NET in order to deal with security breaches.

This section describes the ground rules and the actions component vendors and application developers need to take to maintain compatibility and, if possible, take advantage of new versions.

5.6.1. CLR Side-by-Side Execution

Even though the CLR and the various .NET application frameworks consist of many assemblies, all are treated as a single versioning unit. Multiple versions of these units can coexist on any given machine. This is called CLR side-by-side execution. Side-by-side execution is possible because .NET is deployed in the GAC, and the GAC supports side-by-side execution of different versions of the same assembly. As a result, different .NET applications can simultaneously use different versions of .NET. It's also possible to install new versions of .NET or remove existing versions. Side-by-side coexistence reduces the likelihood of impacting one application when installing another, because the old application can still use the older .NET version (provided you take certain steps, as described next). Nonetheless, CLR side-by-side execution allows you to choose when to upgrade to the next version, rather than having it ordained by the installation of the latest CLR version.

If you choose to take advantage of features available in a newer version of .NET but not in older ones, your components will no longer be compatible with older versions. As a result, you must test and certify your components against each .NET version and state clearly in the product documentation which .NET versions are supported.


5.6.2. Version Unification

All .NET applications are hosted in an unmanaged process, which loads the CLR DLLs. That unmanaged process can use exactly one version of each CLR assembly. In addition, the version number of the CLR dictates which version of the .NET application frameworks you can use, because the CLR and its application frameworks assemblies are treated as a single versioning unit. The fact that .NET always runs a unified stack of framework assemblies is called version unification. Unification is required because the CLR and the .NET application frameworks aren't designed for mixing and matching (say, with some assemblies coming from version 1.1 and some from version 2.0 of the .NET Framework).

Typically, a .NET application contains a single EXE application assembly used to launch the process, and potentially multiple other assemblies (class library assemblies or application assemblies) loaded into that process. Unification means that in a process containing a managed application, the EXE application assembly and the assemblies it loads use the same .NET version. It's up to the EXE used to launch the process to select the CLR and application frameworks version; the assemblies it loads have no say in the matter. For example, all of the assemblies in the first release of .NET (.NET 1.0) have the version number 1.0.3300.0. All assemblies in the second release of .NET (.NET 1.1) are numbered 1.1.5000.0. Imagine a machine that has both versions installed. When an EXE assembly uses .NET version 1.1.5000.0, it makes all assemblies it loads use 1.1.5000.0, even if they are compiled with version 1.0.3300.0. This is not a problem, because .NET 1.1 is backward-compatible with .NET 1.0. Conversely, however, if the EXE assembly selects version 1.0.3300.0, all the assemblies it loads will use version 1.0.3300.0, even if they require the newer features of 1.1.5000.0. This may cause your application to malfunction.

The next section describes how to indicate explicitly which CLR versions your application supports. In any case, with unification and side-by-side execution, it's possible at the same time for one application to use version 1.0.3300.0 and another application to use 1.1.5000.0, even if they interact with each other.

Avoid using custom version-binding policies to override unification. It can lead to undetermined results.


5.6.3. Specifying a CLR Version

On a given machine, there can be any combination of CLR versions. Applications can implicitly rely on a default CLR version-resolution policy, or they can provide explicit configuration indicating the supported CLR versions.

5.6.3.1 Default version binding

If an application doesn't indicate to .NET which CLR versions it requires, the application is actually telling .NET that any compatible CLR version is allowed. In that case, .NET detects the CLR version the application was compiled with and uses the latest compatible CLR version on the machine. To that end, .NET is aware of which CLR versions are backward-compatible with other versions. Presently, Microsoft considers all newer .NET versions to be backward-compatible. Note that CLR backward compatibility is not the same as forward compatibility. Backward compatibility deals with the question of whether an assembly built against an older CLR version can execute on a newer CLR version. Forward compatibility deals with whether an assembly that was built against a newer CLR version can execute on an old CLR version. Backward compatibility is mostly the product of changes to type definition and type behavior. Forward compatibility is governed by the metadata version. .NET 1.0 and .NET 1.1 have the same metadata version, so they are both backward- and forward-compatible with respect to each other. .NET 2.0 has a new metadata version, so it is only considered backward-compatible.NET 2.0 assemblies require the .NET 2.0 runtime.

Table 5-1 depicts the CLR version-compatibility matrix. The lefthand column lists the CLR version against which an assembly was built, and the rest of the columns list whether those assemblies can run against the other CLR versions.

Table 5-1. CLR version compatibility

Assembly\CLR version

1.0

1.1

2.0

1.0

+

+

+

1.1

+

+

+

2.0

-

-

+


A similar compatibility table is maintained in the Registry. .NET uses that table when deciding which CLR version to provide for an application (the default is to always use the highest available compatible version). Applications that rely on this default policy are typically mainstream applications that use the subset of types and services supported by all the CLR versions. Applications that take advantage of new features or types can't use the default policy, because they may be installed on machines with only older versions of the CLR. Similarly, applications that use features that are no longer supported can't use the default policy.

5.6.3.2 Specifying supported CLR versions

Using the default version may cause applications to run against CLR versions they were not tested for, resulting in undetermined behavior. If you don't want your application to rely on the default version-binding policy, and you want it to have deterministic behavior, you can provide explicit version configuration. In such cases, the application must indicate in its configuration file which versions of the CLR it supports, using the startup tag with the supportedRuntime attribute:

     <?xml version="1.0"?>     <configuration>        <startup>           <supportedRuntime version="v2.0.5500.0"/>           <supportedRuntime version="v1.1.5000.0"/>        </startup>        </configuration> 

Generally speaking, you should not add a CLR version to the list without going through a testing and verification cycle to ensure version compatibility. The order in which the CLR versions are listed indicates priority. .NET will try to provide the first CLR version to the application. If that version isn't available on the machine, .NET tries to use the next version down the list, and so on. If none of the specified versions is available, .NET refuses to load the application and presents a message box asking the user to install at least one of the supported versions specified in the configuration file. Note that the startup directive overrides any default behavior .NET can provide, meaning that even if another compatible version is available on the machine, if it is not listed in the configuration file .NET will refuse to run the application. Consequently, if an application explicitly lists its supported CLR versions, it can't be deployed on a machine with a new version that isn't listed.

Visual Studio 2005 can build only applications targeting CLR version 2.0.




Programming. NET Components
Programming .NET Components, 2nd Edition
ISBN: 0596102070
EAN: 2147483647
Year: 2003
Pages: 145
Authors: Juval Lowy

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