Understanding .NET Versioning
Unlike COM versioning, the versioning mechanisms in .NET do not rely upon binary compatibility between interfaces. Rather, the entire .NET DLL (known as an assembly) is versioned as a unit. All interfaces, classes, enums, and other types within a single .NET assembly carry the same version number assigned to the assembly as a whole. Also unlike COM versioning which uses only a two-part version number, .NET version numbers contain four parts. These version numbers have the following form:
Since IVI-COM drivers are exposed to .NET client applications (such as C# and VB.NET applications) via a .NET interop assembly, the IVI driver must properly manage the .NET interop assembly version number to ensure client applications do not break when new driver versions are introduced.
The key to understanding .NET versioning is realizing that the version number of an assembly is embedded into each client application that uses the assembly. When a C# client application adds a reference to an IVI-COM driver and compiles the code, the full four-part version number of the driver interop assembly is "baked" into the client DLL. Whenever that client application runs, the .NET runtime will verify that the version number of the loaded interop assembly matches the version number of the interop assembly against which the client application was originally built. If the two version numbers do not match EXACTLY (all four parts must match), then an exception is generated and the client application will not run.
At first glance, it might seem that distributing an updated version of an IVI driver would require all .NET applications to be recompiled, so that the new version number of the interop assembly would be embedded in the client application. This would be a most intrusive versioning scheme indeed. Fortunately, the .NET Framework provides a special mechanism that allows existing client applications to load newer versions of assemblies without being recompiled. This mechanism relies on special companion files known as policy files. These are discussed in the next section.
A .NET policy file is a specially formatted and specially named DLL companion file that ships alongside a .NET assembly, such as an IVI driver interop assembly. The policy file contains special statements known as binding re-direct statements. These binding re-directs tell the .NET runtime to load a designated version of an assembly (typically a newer version) instead of an existing version that a client application might be compiled against. This allows .NET client applications to be seamlessly upgraded to newer versions without having to be recompiled.
As an example, consider the following scenario. An end user builds a C# client application using version 22.214.171.124 of an IVI-COM driver. Several months later, the vendor of the IVI-COM driver ships version 126.96.36.199. If the end user installs version 188.8.131.52 of the driver and tries to run the application, it will fail to load because the application contains a reference to version 184.108.40.206 of the driver's interop assembly. What the driver vendor must do is create and distribute a policy file that contains the appropriate statements to say to the .NET runtime -- "for any client application that attempts to load version 220.127.116.11, load version 18.104.22.168 instead". With the policy file installed alongside the driver's interop assembly, any client applications using version 22.214.171.124 of the driver will automatically be "re-directed" to load version 126.96.36.199. In fact, version 188.8.131.52 of the driver need not even be installed anywhere on the client machine.
Nimbus will automatically create the appropriate policy files for an IVI-COM driver given simple compatibility statements the driver developer makes about the driver. The General Page of the Driver Settings Editor contains a list of compatible versions. This allows the driver developer to express which previous versions of the driver are compatible with the current version. For each compatible version listed, Nimbus will create a policy file and integrate it with the driver installer. Each policy file contains the appropriate binding re-direct statements to upgrade .NET clients from that specific version to the latest version of the driver.
The .NET runtime requires a very specific name for policy files in order to properly mate them with their associated assemblies at runtime. The policy files must have the following form:
In the above name, the major and minor version numbers refer to the previous version to upgrade FROM. For example, for a driver named "Acme4321" shipped by a company called "Acme", the policy file for upgrading clients from version 1.0 to the latest version would be named as follows:
One fundamental limitation of .NET versioning is that policy files can only be used to re-direct versions based on the major and minor version numbers. Even though the .NET runtime uses all four parts of the version number in resolving assembly versions at runtime, the policy file mechanism can only discriminate assemblies based on the major and minor portions of the four-part version. This explains why the standard format policy file name above only contains a two-part version number. What this means is that you cannot upgrade version 184.108.40.206 to a different assembly than the one to which you upgrade version 220.127.116.11. Any client compiled against 1.0.X.X would be upgraded to the same assembly version. In practice, this is rarely an issue for IVI drivers.
Policy files are DLLs that must be installed in the global assembly cache (GAC) just as the interop assemblies themselves. Thus, they must ultimately be signed with a digital signature just like the driver interop assemblies. Nimbus automatically manages the digital signature for policy files in the same way it manages them for interop assemblies.
For more information on digitial signatures for IVI drivers, see the topic Supporting .NET Client Applications.
Download a complete CHM version of this documentation here.