Assembly Learning Experience
Author: Wang xuepeng www.ASPCool.com time: 2004-12-16
Note:
Recently, I started to reorganize my. NET knowledge. It would be better to repeat it over a thousand times,
So I want to write down my learning experience and have prepared a reference.
You are all prawns. If you have any errors or errors, please leave them blank. Thank you.
There are two parts: First, some concepts that must be understood, and then a complete example to illustrate them one by one.
These concepts;
Part 1 (concept)
Managed Module)
The managed module is a standard Windows executable (PE) file that requires CLR execution.
Metadata (Metadata)
In short, metadata is a collection of data tables. In these tables, some of them are used
Describes the content defined in the managed module (such as the defined types and their members ).
Describes the content referenced in a managed module (such as the referenced type and their members ).
URL: ms-help: // MS. MSDN
QTR.2004APR. 1033/cpguide/html/cpconmetadataoverview.htm
Assembly Manifest)
The Assembly List is a collection of other metadata tables. These tables describe the files that make up the assembly,
Public export types implemented in all Assembly files, as well as some assembly-related resource files or data files.
Ms-help ://
MS. MSDNQTR.2004APR. 1033/cpguide/html/cpconAssemblyManifest.htm
1. Concept of Assembly:
First, an assembly is one or more managed modules and a logical combination of some resource files. Because it is a logical combination, the logical representation of the Assembly and the physical representation can be separated from each other. How to divide code and resources into different files is totally dependent on us. For example, we can put some rarely used types or resources in a separate assembly module, and then download them from the web as needed (for example, when used for the first time. If they are not used, they will not be downloaded. This saves both disk space and installation time. The Assembly allows us to split the deployment of files, and treat all files as a separate set.
Second, because CLR directly deals with the Assembly, the Assembly is also Component reuse, and the minimum unit for implementing security policies and version policies (security policies, version information can only be added to the assembly ).
Note: An assembly is a logical combination that can contain many files. Most assemblies (for example, those created using Visual studio.netare generally single-file sets, and only one. EXE or. dll file exists (currently. Net assemblies only have these two formats ). In this case, the Assembly List (manifest) is directly embedded into a single-file assembly. However, you can also create a multi-file assembly by using the Generator program generation tool plug-in (al.exe. You can also create only one assembly that contains the list.
2. Concept of strong naming assembly
Because different companies may develop an assembly with the same name, if these assembly is copied to the same directory, the last installed assembly will replace the previous Assembly. This is why the famous windows "DLL hell" appeared.
Obviously, it is not enough to distinguish an assembly by file name. CLR must support a mechanism to uniquely identify an assembly. This is the so-called strongly-named assembly.
A strongly-named Assembly contains four unique flag Assembly features: File Name (without extension), version number, language and cultural information (if any), and public key.
This information is stored in the Assembly List (manifest. The list contains the Assembly metadata and is embedded in a file of the Assembly.
The following string identifies four different assembly files:
"Mytype, version = 1.0.1.0,
Culture = neutral, publickeytoken = bf5779af662fc055"
"Mytype, version = 1.0.1.0,
Culture = en-US, publickeytoken = bf5779af662fc055"
"Mytype, version = 1.0.2.0,
Culture = neturl, publickeytoken = bf5779af662fc055"
"Mytype, version = 1.0.2.0,
Culture = neutral, publickeytoken = dbe4120289f9fd8a"
If a company wants to uniquely identify its assembly, it must first obtain a public/private key pair and then associate the common key with the Assembly. There are no two companies that have the same public/private key pair. This distinction allows us to create an assembly with the same name, version, and language and cultural information without causing any conflict.
The weak naming Assembly corresponds to the strongly naming assembly. (In fact, it is a common assembly that is not strongly named ). The two types of Assembly have the same structure. All use the same PE file format, PE Header, CLR header, metadata, and list (manifest ). The real difference between the two is that a strongly-named assembly has a publisher's public/private key pair signature, and the public/private key pair uniquely identifies the Assembly publisher. Using public/private key pairs, we can identify the uniqueness of the assembly, implement security policies and version control policies, this unique capability to identify an Assembly enables applications to implement certain "known security" policies (such as trusting a company's assembly) when attempting to bind a strongly-named assembly ).
3. How to Create a strongly-named assembly (strong name Assembly)
To create a strongly-named assembly, you must first obtain a utility that uses a strongly-named
(Strong name utility, which is included in sn.exe and. Net SDK.
The following describes some usage of sn.exe. To generate a public/private key pair:
A) Sn-K mycompany. Keys
Create a file named mycompany. Keys. The mycompany. Keys file contains the public and private keys stored in binary format.
B) view the public key:
First, generate a file containing only the public key: Sn-P
Mycompany. Keys mycompany. publickey
Then use the-TP parameter to view: Sn-TP mycompany. publickeys
Public Key is
00240000048000009400000006020000002400005253413
10004000001000100bb7214723ffc13901343df4b9c464ebf
7ef4312b0ae4d31db04a99673e8163768cc0a2a7062e731d
Beb83b869f0509bf8009e90db5c8728e840e782d2cf928dae
35c2578ec55f0dda-65a30b37f8636c08789976d8ee9fe9a5
C4a0435f0821738e51d6bdd6e6711a5acb620018658cce93
Df37d7e85f9a0da-a5821353995ce8
Public Key token is 2dc940d5439468c2
After the public key/private key pair is created, it is easy to create a strongly-named assembly. You only need to add the system. reflection. assemblykeyfileattribute feature to the source code :? [Assembly: assemblykeyfile ("mycompany. Keys")]
Note: the extension of the public/private key pair file can be arbitrary (or not), because it is read in metadata format during compilation.
4. Deployment method of the Assembly
An assembly can be deployed in two ways:
A) Private Mode
An assembly deployed in the same directory as an application is called a private deployment assembly. Weak naming Assembly can only be deployed in private mode.
B) Global Mode
In the global deployment mode, the Assembly is deployed in some places that the CLR knows. When the CLR searches for an assembly, it will know where to find it. Strongly-named assembly can be either private or global.
Assembly Type
Private deployment allowed?
Can I perform global deployment?
Common Assembly
Yes
No
Strongly-named assembly
Yes
Yes
5. How to deploy strong-name assembly and GAC
A) Concept of GAC
If an Assembly is to be accessed by multiple applications, it must be placed in a directory that is known to the CLR, and when the CLR detects a reference to the Assembly, it must be able to automatically search for the Assembly in this directory. This known directory is called GAC (Global Assembly Cache), which is the Global Assembly Cache. It is generally located in the following directory: <System Drive >:\ Windows \ Assembly \ GAC.
The role of GAC is to provide the CLR with a known and definite directory to find the referenced assembly.
B) Internal Structure of GAC
GAC is a special structured directory. If you use Windows Explorer to browse it, you will think it is just a common directory that contains many sets. In fact, this is not the case. You can view it in the command line and find that it actually contains many sub-directories. The sub-directory names and Assembly names are the same, but they are not the actual assembly, the actual Assembly is located in the directory corresponding to the Assembly name. For example, if you enter the GCFWK subdirectory, you will find many subdirectories. Each GCFWK. dll installed on the machine to GAC has a subdirectory in GCFWK.
Only one directory indicates that only one version of GCFWK assembly is installed. The actual program set is saved in the directory of each corresponding version. The name of the directory is separated into (Version) _ (Culture) _ (PublicKeyToken )".
The GCFWK Language and Culture Information is netture, which indicates 0.0.0 _ bf5779af662fc055 ". It indicates: "GCFWK, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = bf5779af662fc055" if the Language and Culture Information is "ja", it indicates "1.0.0.0 _ ja_bf5779af662fc055"
It indicates: "GCFWK, Version = 1.0.0.0, Culture = ja, PublicKeyToken = bf5779af662fc055"
C) deploy a strongly-named assembly to GAC
GAC contains many subdirectories, which are generated using an algorithm. We 'd better not manually copy the Assembly to GAC. Instead, we should use tools to do this. Because these tools know the internal structure of GAC J
The most common tool in development and testing is gacutil.exe. Registering an assembly in GAC is similar to registering an assembly with COM, but it is relatively easier:
1. Add the Assembly to GAC: GACUtil/I sample. dll (the parameter/I indicates installation)
2. Remove the Assembly from GAC GACUtil/u sample. dll (remove the parameter/u)
Note: a weak naming assembly cannot be installed in GAC.
If you try to add the weak naming assembly to GAC, you will receive the error message :"
Failure adding assembly to the cache: Attempt to install an assembly without a strong name"
D) Private deployment of Strongly-named assembly
Installing an assembly to GAC has several advantages. First, GAC enables many programs to share the assembly, which reduces the physical memory used as a whole. Second, we can easily deploy a new version of the assembly to GAC, and through a publisher policy (almost a redirection method, such as changing the configuration file of a program with the original referenced version 1.0.0.0, instead, let the program reference the Assembly whose version is 2.0.0.0 to use the new version. Finally, GAC also provides the side-by-side management mode for the assembly of different versions. However, GAC's security policy usually only allows the Administrator to change. At the same time, installing an assembly in GAC also breaks the promise of a simple copy deployment of the. NET Framework.
In addition to deploying a strongly-named assembly to GAC or in a private deployment mode, we can also deploy the strongly-named assembly in a directory that is only known to a small number of programs. Configure the XML configuration files of each application and point them to a public directory. In this way, the CLR will know where to find the strongly-named assembly at runtime. But this may cause the "DLL Hell" problem, because no program can control when the Assembly will be uninstalled. This is not encouraged in. NET.
6. Parallel Execution (Side-By-Side)
Here is an example of a strongly-named assembly:
First, an app.exe assembly is bound to a calculus. dll assembly of version 2.0.0.0 and an advmath. dll assembly of version 3.0.0.0. The advmath. dll assembly is bound to a calculus. dll assembly of version 1.0.0.0. For example:
An application that requires different versions of the calculus. dll assembly
CLR can load multiple files with the same name but different paths to the same address space. net is called side-by-side execution. It is a key technology to solve the "DLL hole" Problem in windows.
For example, both. NET Framework 1.0 and. NET Framework 1.1 can be run on the same machine, which uses side-by-side execution.
For more information, see:
MS-help: // Ms. msdnqtr.2004apr. 1033/cpguide/html/cpconSide-by-SideExecutionTop.htm
Http://www.microsoft.com/china/msdn/archives/library/dnnetdep/
Html/sidexsidenet. asp
7. How does CLR parse type references?
When parsing a referenced type, CLR can find this type in one of the following three places:
· The same file?
Access to the same file type has been determined during compilation. CRL loads the referenced type directly from the file. After loading, the program continues to run.
· Different files and the same assembly
CLR first ensures that the referenced file is in the FileDef table of the current Assembly List. CLR then finds the referenced file in the directory where the Assembly list file is loaded. When the file is loaded, CLR checks its hash value to ensure the integrity of the file, and then finds the corresponding type member. After loading, the program continues to run.
· Different files and assembly
When the referenced assembly is in a different assembly file, CLR first loads the file containing the list of referenced assembly. If the file does not contain the required type, CLR loads the appropriate file based on the configuration file. This will also find members of the corresponding type. After loading, the program continues to run.
If any errors occur during parsing Type reference, such as file cannot be found, file cannot be loaded, or the hash value does not match, the system will throw an exception.
Demonstrate the type binding process:
Assembly Type
Can weak naming assembly be referenced?
Can I reference a strongly-named assembly?
Common Assembly
Yes
Yes
Strongly-named assembly
No
Yes
Part 2 (example)
The following is a complete example to illustrate the concepts mentioned above one by one to deepen understanding.
The example contains seven files (in the main directory ):
The main directory is... /Assembly ---- source program directory
... /Assembly/Bin ---- directory of the compilation result output, that is, the main object of the application
.
File Name
Type
Description
App. cs
Code source file
Main Program, including program entry,
Belongs to namespace1
ClassA. cs
Code source file
Type A, including A static method,
Belongs to namespace1
ClassB. cs
Code source file
Type B, including a static method,
Belongs to namespace2
AssemblyInfo. cs
Code source file
Contains Assembly signature information,
Version Information
App. Key
Public Key/private key pair File
Used to sign an assembly,
Generate strongly-named assembly
App. PublicKey
Contains only common keys
Only store the total key,
Use sn.exe to view
App.exe. config
Xml format configuration file
App.exe application configuration file
Source code
App. cs
Namespace namespaceA {
Public class App {
Static void Main (string [] args ){
System. Console. WriteLine (ClassA. ShowMe ());
System. Console. WriteLine (namespaceB. ClassB. ShowMe ());
}
}
}
ClassA. cs
Namespace namespaceA {
Public class ClassA {
Public static string ShowMe ()
{
Return "This is ClassA ";
}
}
}
ClassB. cs
Namespace namespaceB {
Public class ClassB {
Public static string ShowMe (){
Return "This is ClassB ";
}
}
}
AssemblyInfo. cs
//////////////////////////////////////// ////////////////////////////////////////
// Module: AssemblyInfo. cs
//////////////////////////////////////// ////////////////////////////////////////
Using System. Reflection;
//////////////////////////////////////// ////////////////////////////////////////
// Set CompanyName, LegalCopyright, and LegalTrademarks
[Assembly: AssemblyCompany ("App Company")]
[Assembly: AssemblyCopyright ("Copyright (C) 2004 @ App Company")]
[Assembly: AssemblyTrademark ("App is a test only program")]
//////////////////////////////////////// ////////////////////////////////////////
// Set ProductName and ProductVersion
[Assembly: AssemblyProduct ("App Product")]
[Assembly: AssemblyInformationalVersion ("1.0.0.0")]
//////////////////////////////////////// ////////////////////////////////////////
// Set FileVersion and AssemblyVersion
[Assembly: AssemblyFileVersion ("1.0.0.0")]
[Assembly: AssemblyVersion ("1.0.0.0")]
[Assembly: AssemblyTitle ("App type assembly")]
[Assembly: AssemblyDescription ("App Aassembly is a test only assembly")]
//////////////////////////////////////// ////////////////////////////////////////
// Set Culture
[Assembly: AssemblyCulture ("")]
[Assembly: AssemblyDelaySign (false)]
[Assembly: AssemblyKeyFile ("App. key")]
[Assembly: AssemblyKeyName ("")]
App. key and App. PublicKey are stored in binary format and cannot be viewed directly. It will be used in the following example
1. Compile the source code into a Managed Module)
Csc/out: bin/classA. module/t: module classA. cs
Parameters:
/Out: Output path
/T: output format. There can be four types:
Library ---- DLL assembly
Exe ---- console executable program (also a type of assembly)
Winexe ---- Windows executable program (also a type of assembly)
Module ---- managed module (part of the Assembly)
Note: the extension of the hosting module can be any (or none), because it is read in metadata format during compilation.
2. Compile the source code into an Assembly)
L compile ClassB into a single file assembly
Csc/out: bin/classB. dll/t: library classB. cs
L compile App. cs, ClassA. module, and ClassB. dll into a multi-file assembly.
Csc/out: bin/App.exe/t: exe app. cs/addmodule: bin/classA. module/r: bin/classB. dll
Parameters:
/Addmodule: add the hosted module to the Assembly/r: Add reference Description: The Assembly generated above is non-strongly-named because it has not passed the Public Key/private signature. The app.exe list of the generated Assembly contains only the description of the classA. module hosting module, and does not include metadata of classa.module. the app.exe and classA. moudle must be in the same directory. When App.exe is running. the type reference in module will go to classA. find the moudel file, if classA. if the moude file does not exist, System. IO. fileNotFoundException. If app.exeis not used in class.module, the existence of classa.modulewill not affect the execution of app.exe (this is one of the advantages of the Assembly mentioned above, and Assembly is a logical combination ).
You can also put shards together in other sub-directories in the main directory. (You can use the application to change the configuration file later to redirect the reference of classB. dll ).
3. modify the application configuration file (app.exe. config) to redirect the reference to classB. dll.
Now app.exe, classa.moudleand classb.dllare all in the bindirectory. app.exe will find all the types it needs during runtime, so it runs normally.
If you create a new directory under the bindirectory, such as a subdirectory, and move classb.dllto the subdirectory, then running app.exe will cause an error. In the same example, system.io.filenotfoundexceptionis incorrect because the classb type required by app.exe cannot be found. In this case, you need to change the add (if not) or the application configuration file. The application configuration file is an XML format configuration file, and the Web. the Config File serves almost the same purpose, and is used to configure the behavior of the application program running.
Note: The configuration file name must be an application name plus a. config file, and must be in the same directory.
For more information, see ms-help: // Ms. msdnqtr.2004apr. 1033/cpguide/html/
Cpconnetapplicationconfigurationscenarios.htm
Content of the app.exe. config file:
<? Xmlversion = "1.0" encoding = "UTF-8"?>
<Configuration>
<Runtime>
<Assemblybindingxmlns = "urn: Schemas-Microsoft-com: ASM. V1">
<Probingprivatepath = "sub"/>
</Assemblybinding>
</Runtime>
</Configuration> when app.exe is running, it finds classb. dll in the sub directory of the main directory and continues the row.
Note:
When the CLR needs to locate a dataset, it will scan several subdirectories of the application. The following is the sequence in which the CLR scans a dataset:
... /ASSEMBLY/bin/classb. dll.
... /ASSEMBLY/bin/classb. dll.
... /ASSEMBLY/bin/SUB/classb. dll.
... /ASSEMBLY/bin/SUB/classb. dll.
... /ASSEMBLY/bin/classb. EXE.
... /ASSEMBLY/bin/classb. EXE.
... /ASSEMBLY/bin/SUB/classb. EXE.
... /ASSEMBLY/bin/SUB/classb. EXE.
NOTE: If app.exe references a strongly-named assembly, CLR first searches for the Assembly in GAC and then searches for the Assembly in the above Order.
4. Create and view public/private key pair files
You can use the. NET sdktool (sn.exe) to create a public/private key pair file. First, create a public/private key pair file.
SN-k App. key
Then, use this file to create a file that only contains the common key:
SN-p App. key App. publickey
Use the-tp parameter to view
SN-tp App. publickey
5. Create a strongly-named assembly
With the public key/private key pair, it is easy to create a strongly-named assembly. You only need
System. Reflection. AssemblyKeyFileAttribute can be added to the source code.
[Assembly: AssemblyKeyFile ("App. key")]
It is generally added to the AssemblyInfo. cs file.
Now, re-build classB. cs to obtain a strongly-named assembly:
Csc/out: bin/classB. dll/t: library classB. cs AssemblyInfo. cs
Run ildasm.exe to check whether the Public Key in Assembly has a large string value. This is the Public Key of the Assembly, which guarantees the uniqueness of the whole sequence set.
[Img] [/img]
6. Add the strongly-named Assembly classB. dll to GAC.
Use gacutil.exe
Add classB. dll to GAC:
GACUtil/I classB. dll
Delete classB. dll and re-Build App.exe:
Csc/out: bin/app.exe/t: exe app. cs/addmodule: bin/classA. module/r: classB. dll
App.exe runs correctly, indicating that classB. dll has been successfully added to GAC and becomes a shared assembly. Rules for mutual Assembly reference:
Assembly Type
Can weak naming assembly be referenced?
Can I reference a strongly-named assembly?
Common Assembly
Yes
Yes
Strongly-named assembly
No
Yes
Remove classB. dll from GAC: GACUtil/u classB
Note:
You cannot specify the extension when removing an assembly (because each assembly in GAC is a directory instead of an actual assembly ).
If classb.dllis not a program set with a strong name, and you want to build app.exe as a strongly-named one, an error will occur:
Error CS1577: Assembly generation failed -- Referenced assembly 'classb 'does not have a strong name
You can try it. J
7. Example of parallel execution (Side-By-Side)
Http://www.microsoft.com/china/msdn/archives/library/
Dnnetdep/html/sidexsidenet. asp
References:
L applied Microsoft. NET Framework programming ---- Jeffrey Richter
L msnd Library
L I would like to thank Liu Lin for her great help.
<End>