C # Assembly series 13: how to let CLR select different versions of the Assembly,
This article describes how to select the version assembly to run and switch the assembly version if multiple version Assembly versions exist.
Generate different versions of non-strong name assembly
□Generate an assembly of a specific version
→ Clear the as folder of drive F, and the following files are left.
→ View the Cow. cs File
using System;
using System.Reflection;
[assembly: AssemblyVersion("3.3.3.3")]
public class Cow
{
public static void Moo()
{
Console.WriteLine("Moo version 1");
}
}
→ Compile Cow. cs and generate Farm. dll assembly
Note: Farm. dll is not a strongly-named assembly
→ Compile the MainClass. cs file, generate an executable file, and reference Farm. dll.
→Run mainclass.exe
□Generate an assembly of another version
→ Modify the Cow. cs file and save
using System;
using System.Reflection;
[assembly: AssemblyVersion("8.8.8.8")]
public class Cow
{
public static void Moo()
{
Console.WriteLine("Moo version 2");
}
}
→ Re-compile Cow. cs and regenerate Farm. dll
Then run mainclass.exe.
The second generation of Farm. dll has taken effect.
→ Modify the class name BigCow in Cow. cs and save
using System;
using System.Reflection;
[assembly: AssemblyVersion("8.8.8.8")]
public class BigCow
{
public static void Moo()
{
Console.WriteLine("Moo version 2");
}
}
→ Content in MainClass. cs is as follows:
using System;
class MainClass
{
static void Main()
{
Cow.Moo();
}
}
→ Re-compile Cow. cs and generate Farm. dll again
When the supervisor runs mainclass.exe again, an error is returned.
Because in MainClass. cs, the view looks for Cow, but it does not exist, and it has become BigCow.
Generate strong-name Assembly versions
□Generate strongly-named assembly
Remove farm.dlland mainclass.exe
→ Change Cow. cs to the following and save
using System;
using System.Reflection;
[assembly: AssemblyVersion("3.3.3.3")]
public class Cow
{
public static void Moo()
{
Console.WriteLine("Moo version 1");
}
}
→ Re-compile Cow. cs. Use the key this time.
→ Re-compile MainClass. cs
Then run mainclass.exe.
□Generate another assembly with a strong name
→ Modify Cow. cs as follows, and change the version and method implementation.
using System;
using System.Reflection;
[assembly: AssemblyVersion("8.8.8.8")]
public class Cow
{
public static void Moo()
{
Console.WriteLine("Moo version 2");
}
}
→ Re-compile Cow. cs, but use the same key last time
When ingress runs mainclass.exe, an error is returned.
This indicates that the master program cannot find the first version of the strongly-named assembly.
Coexistence of Assembly versions with different strong names
□Create a strong-name Assembly for a specific version
→ Create a Farm folder
→ Change Cow. cs to the first version and save
using System;
using System.Reflection;
[assembly: AssemblyVersion("3.3.3.3")]
public class Cow
{
public static void Moo()
{
Console.WriteLine("Moo version 1");
}
}
→ Compile Cow. cs and regenerate Farm. dll
→Run mainclass.exe
Note: When the Assembly becomes the first version of the strongly-named assembly, the program can run normally again.
→ Move Farm. dll to the Farm folder
The supervisor runs mainclass.exebecause it has already customized the method for searching the Assembly during CLR runtime in mainclass.exe. config, so it runs normally.
□Create a strong-name assembly for another version
→ Modify Cow. cs to the second version again and save
using System;
using System.Reflection;
[assembly: AssemblyVersion("8.8.8.8")]
public class Cow
{
public static void Moo()
{
Console.WriteLine("Moo version 2");
}
}
→ Compile Cow. cs
Note: In this case, there is a Farm. dll in the Farm file, which is the first version.
→Runs mainclass.exe and returns an error again.
The problem is: there are two versions of Farm. dll, And the CLR runtime cannot decide which version of Farm. dll to use. However, you can first write down the PublicKeyToken: 863de8402b3a9978
Tell CLR which version of the strong-name assembly is executed
Now we have two Farm. dll files at the same time. How can we make the CLR decide which version to specify?
-- Set in mainclass.exe. config
→Suppose we need to use the Farm. dll assembly in the Farm folder and set it as follows:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Farm" publicKeyToken="863de8402b3a9978" />
<bindingRedirect oldVersion="3.3.3.3" newVersion="8.8.8.8" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Then run mainclass.exe.
Everything works.
Use a strong-name assembly of the old version
Modify mainclass.exe. config and set it as follows:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Farm" publicKeyToken="863de8402b3a9978" />
<bindingRedirect oldVersion="8.8.8.8" newVersion="3.3.3.3" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
→ Delete the Farm. dll in the as folder and move the Farm. dll in the as folder to the as folder.
Then run mainclass.exe.
Everything works. The old version of Strongly-named assembly is already in use.
Summary:
○ If you want the CLR to select the version of the assembly to run, the Assembly must be a strongly-named assembly.
○ Version switching is set in "executable file name .exe. config"
"C # Assembly series" includes:
C # Assembly series 01, use NotePad to write C # And IL code, use the DOS command to compile the assembly, and run the C # Assembly series 02 program, use NotePad to view the IL code C # Assembly series 03 of the executable assembly, reference multiple module C # Assembly series 04, when an Assembly contains multiple modules, you can understand the keyword internal C # Assembly generation 05, so that the Assembly contains multiple modules C # Assembly generation 06, assembly list, differences between EXE and dll c # Assembly generation 07, tampered with assembly C # Assembly generation 08, set assembly version C # Assembly generation 09, assembly signature C # Assembly Generation 10, strong name assembly C # Assembly generation 11, Global Assembly Cache C # Assembly generation 12, C # compiler and CLR how to find assembly C # Assembly generation 13, how to let CLR select different versions of Assembly
References:
Http://www.computersciencevideos.org/created by Jamie King
C Language & |! What are
& Is the address fetch operator used to extract the address of a variable.
For example, if you define a variable, the system will allocate a space in the memory during compilation.
The location of the space in the memory is its address. & Extract its address.
E. g int a; assign an address to it during compilation, for example, 2000; & a is 2000.
If an integer pointer Variable p, p = & a; is defined, the address 2000 of a is assigned to p. P = 2000 after running.
Another example is scanf ("% d", & a). When you enter 3, it first knows the address of a according to & a, and finds the space of a in the memory by the address, write 3 to this space.
* Is a pointer operator, which is opposite to &. It extracts the value of a Variable Based on the address of the variable.
For example, * the value of a is 3 of variable.
The following is a summary of the pointer used in the definition and description.
Int * p; defines a pointer to integer data.
Int * p [n]; defines the pointer array p, which consists of n pointer elements pointing to integer data.
Int (* p) [n]; p is the pointer variable pointing to a one-dimensional array containing n elements.
Int * p (); p is the function that returns a pointer pointing to integer data.
Int (* p) (); p is the pointer to the function. This function returns an integer value.
Int ** p; p is a pointer variable that points to an integer Data Pointer variable.
If you want to learn more about the system, you can refer to tan haoqiang's c Programming (the third edition), which is easy to understand. Is a good C language learning material.
C Language & |! What are
& Is the address fetch operator used to extract the address of a variable.
For example, if you define a variable, the system will allocate a space in the memory during compilation.
The location of the space in the memory is its address. & Extract its address.
E. g int a; assign an address to it during compilation, for example, 2000; & a is 2000.
If an integer pointer Variable p, p = & a; is defined, the address 2000 of a is assigned to p. P = 2000 after running.
Another example is scanf ("% d", & a). When you enter 3, it first knows the address of a according to & a, and finds the space of a in the memory by the address, write 3 to this space.
* Is a pointer operator, which is opposite to &. It extracts the value of a Variable Based on the address of the variable.
For example, * the value of a is 3 of variable.
The following is a summary of the pointer used in the definition and description.
Int * p; defines a pointer to integer data.
Int * p [n]; defines the pointer array p, which consists of n pointer elements pointing to integer data.
Int (* p) [n]; p is the pointer variable pointing to a one-dimensional array containing n elements.
Int * p (); p is the function that returns a pointer pointing to integer data.
Int (* p) (); p is the pointer to the function. This function returns an integer value.
Int ** p; p is a pointer variable that points to an integer Data Pointer variable.
If you want to learn more about the system, you can refer to tan haoqiang's c Programming (the third edition), which is easy to understand. Is a good C language learning material.