.NET:CLR via C# Shared Assemblies and Strongly Named Assemblies
Two Kinds of Assemblies, Two Kinds of Deployment

A strongly named assembly consists of four attributes that uniquely identify the assembly: a file name (without an extension), a version number, a culture identity, and a public key. Because public keys are very large numbers, we frequently use a small hash value derived from a public key. This hash value is called a public key token. The following assembly identity strings (sometimes called an assembly display name) identify four completely different assembly files.
- "MyTypes, Version=1.0.8123.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
- "MyTypes, Version=1.0.8123.0, Culture="en-US", PublicKeyToken=b77a5c561934e089"
- "MyTypes, Version=2.0.1234.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
- "MyTypes, Version=1.0.8123.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
Giving an Assembly a Strong Name
Here’s what it means to sign a file: When you build a strongly named assembly, the assembly’s FileDef manifest metadata table includes the list of all the files that make up the assembly. As each file’s name is added to the manifest, the file’s contents are hashed, and this hash value is stored along with the file’s name in the FileDef table. You can override the default hash algorithm used with AL.exe’s /algid switch or apply the assembly-level System.Reflection.AssemblyAlgorithmIdAttribute custom attribute in one of the assembly’s source code files. By default, a SHA-1 algorithm is used.
After the PE file containing the manifest is built, the PE file’s entire contents (except for any Authenticode Signature, the assembly’s strong name data, and the PE header checksum) are hashed, as shown in Figure 3-1. This hash value is signed with the publisher’s private key, and the resulting RSA digital signature is stored in a reserved section (not included in the hash) within the PE file. The CLR header of the PE file is updated to reflect where the digital signature is embedded within the file.

when you compile your source code, the compiler detects the types and members that your code references. You must specify the referenced assemblies to the compiler. For the C# compiler, you use the /reference compiler switch. Part of the compiler’s job is to emit an AssemblyRef metadata table inside the resulting managed module. Each entry in the AssemblyRef metadata table indicates the referenced assembly’s name (without path and extension), version number, culture, and public key information.
AssemblyRef #1 (23000001)
-------------------------------------------------------
Token: 0x23000001
Public Key or Token: b7 7a 5c 56 19 34 e0 89
Name: mscorlib
Version: 4.0.0.0
Major Version: 0x00000004
Minor Version: 0x00000000
Build Number: 0x00000000
Revision Number: 0x00000000
Locale: <null>
HashValue Blob:
Flags: [none] (00000000)
Assembly
-------------------------------------------------------
Token: 0x20000001
Name : L
Public Key : 00 24 00 00 04 80 00 00 94 00 00 00 06 02 00 00 00 24 00 00 52 53 41 31
: 00 04 00 00 01 00 01 00 bb ee e9 61 d3 89 57 8a 23 34 b6 00 c7 31 f6 d1
: 9b 76 02 06 c7 b4 ff 8f 96 3a 53 c6 dc 96 c9 19 70 55 4b f2 8f 0f 83 9b
: c3 29 f5 89 3b 64 96 41 fd 79 1b ff 5e f6 c1 e0 1b 5e a0 c8 d0 18 b8 74
: 41 d2 ef 78 55 9b 3d ff 18 a6 76 fa 4e 0d 73 89 2b 53 1f d5 b0 1c 27 72
: ae 9e f6 ad 90 04 7b 86 d3 a5 01 a9 f7 a0 1b e0 bb 2b 99 9f ce 30 4b c2
: d9 b9 c2 20 b8 40 0a 76 a2 23 ae 25 02 93 1b d9
Hash Algorithm : 0x00008004
Version: 1.0.0.0
Major Version: 0x00000001
Minor Version: 0x00000000
Build Number: 0x00000000
Revision Number: 0x00000000
Locale: <null>
Flags : [PublicKey] (00000001)
Strongly Named Assemblies Are Tamper-Resistant
Signing an assembly with a private key and embedding the signature and public key within an assembly allows the CLR to verify that the assembly has not been modified or corrupted. When an assembly is installed into the GAC, the system hashes the contents of the file containing the manifest and compares the hash value with the RSA digital signature value embedded within the PE file (after unsigning it with the public key). If the values are identical, the file’s contents haven’t been tampered with. In addition, the system hashes the contents of the assembly’s other files and compares the hash values with the hash values stored in the manifest file’s FileDef table. If any of the hash values don’t match, at least one of the assembly’s files has been tampered with, and the assembly will fail to install into the GAC.
When strongly named assembly files are loaded from a location other than the GAC (via the application’s base directory or via a codeBase element in a configuration file), the CLR compares hash values when the assembly is loaded. In other words, a hash of the file is performed every time an application executes and loads the assembly. This performance hit is a tradeoff for being certain that the assembly file’s content hasn’t been tampered with. When the CLR detects mismatched hash values at run time, it throws a System.IO.FileLoadException.
When a strongly named assembly is installed in the GAC, the system ensures that the file containing the manifest hasn’t been tampered with. This check occurs only once, at installation time. In addition, to improve performance, the CLR does not check if a strongly named assembly has been tampered with if the assembly is fully trusted and is being loaded into a fully trusted AppDomain. On the other hand, when a strongly named assembly is loaded from a directory other than the GAC, the CLR verifies the assembly’s manifest file to ensure that the file’s contents have not been tampered with, causing an additional performance hit every time this file is loaded.
Privately Deploying Strongly Named Assemblies
In addition to deploying a strongly named assembly in the GAC or privately, a strongly named assembly can be deployed to some arbitrary directory that a small set of applications know about.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="D_" />
<dependentAssembly>
<assemblyIdentity name="L" publicKeyToken="357f90d80abcd77e" culture="neutral" />
<codeBase version="1.0.0.0" href="file:///E:/Coding/HappyStudy/AssemblyStudy/L/bin/Debug/L.dll" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
How the Runtime Resolves Type References
When resolving a referenced type, the CLR can find the type in one of three places:
- Same file Access to a type that is in the same file is determined at compile time (sometimes referred to as early bound). The type is loaded out of the file directly, and execution continues.
- Different file, same assembly The runtime ensures that the file being referenced is, in fact, in the assembly’s ModuleRef table of the current assembly’s manifest. The runtime then looks in the directory where the assembly’s manifest file was loaded. The file is loaded, its hash value is checked to ensure the file’s integrity, the type’s member is found, and execution continues.
- Different file, different assembly When a referenced type is in a different assembly’s file, the runtime loads the file that contains the referenced assembly’s manifest. If this file doesn’t contain the type, the appropriate file is loaded. The type’s member is found, and execution continues.
If any errors occur while resolving a type reference—file can’t be found, file can’t be loaded, hash mismatch, and so on—an appropriate exception is thrown.
If you want, your code can register callback methods with System.AppDomain’s AssemblyResolve, ReflectionOnlyAssemblyResolve, and TypeResolve events. In your callback methods, you can execute code that resolves the binding problem and allows the application to continue running without throwing an exception.

Advanced Administrative Control (Configuration)
<?xml version="1.0"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="AuxFiles;bin\subdir" />
<dependentAssembly>
<assemblyIdentity name="SomeClassLibrary"
publicKeyToken="32ab4ba45e0a69a1" culture="neutral"/>
<bindingRedirect
oldVersion="1.0.0.0" newVersion="2.0.0.0" />
<codeBase version="2.0.0.0"
href="http://www.Wintellect.com/SomeClassLibrary.dll" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="TypeLib"
publicKeyToken="1f2e74e897abbcfe" culture="neutral"/>
<bindingRedirect
oldVersion="3.0.0.0-3.5.0.0" newVersion="4.0.0.0" />
<publisherPolicy apply="no" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
This XML file gives a wealth of information to the CLR. Here’s what it says:
- probing element Look in the application base directory’s AuxFiles and bin\subdir subdirectories when trying to find a weakly named assembly. For strongly named assemblies, the CLR looks in the GAC or in the URL specified by the codeBase element. The CLR looks in the application’s private paths for a strongly named assembly only if no codeBase element is specified.
- First dependentAssembly, assemblyIdentity, and bindingRedirect elements When attempting to locate version 1.0.0.0 of the culture-neutral SomeClassLibrary assembly published by the organization that controls the 32ab4ba45e0a69a1 public key token, locate version 2.0.0.0 of the same assembly instead.
- codeBase element When attempting to locate version 2.0.0.0 of the culture-neutral Some- ClassLibrary assembly published by the organization that controls the 32ab4ba45e0a69a1 CHAPTER 3 Shared Assemblies and Strongly Named Assemblies 85 public key token, try to find it at the following URL: www.Wintellect.com/SomeClassLibrary.dll. Although a codeBase element can also be used with weakly named assemblies. In this case, the assembly’s version number is ignored and should be omitted from the XML’s codeBase element. Also, the codeBase URL must refer to a directory under the application’s base directory.
- Second dependentAssembly, assemblyIdentity, and bindingRedirect elements When attempting to locate version 3.0.0.0 through version 3.5.0.0 inclusive of the culture-neutral TypeLib assembly published by the organization that controls the 1f2e74e897abbcfe public key token, locate version 4.0.0.0 of the same assembly instead.
- publisherPolicy element If the organization that produces the TypeLib assembly has deployed a publisher policy file (described in the next section), the CLR should ignore this file.
When compiling a method, the CLR determines the types and members being referenced. Using this information, the runtime determines, by looking in the referencing assembly’s AssemblyRef table, the assembly that was originally referenced when the calling assembly was built. The CLR then looks up the assembly/version in the application’s configuration file and applies any version number redirections; the CLR is now looking for this assembly/version.
If the publisherPolicy element's apply attribute is set to yes—or if the element is omitted— the CLR examines the GAC for the new assembly/version and applies any version number redirections that the publisher of the assembly feels is necessary; the CLR is now looking for this assembly/version. Finally, the CLR looks up the new assembly/ version in the machine’s Machine.config file and applies any version number redirections there.
At this point, the CLR knows the version of the assembly that it should load, and it attempts to load the assembly from the GAC. If the assembly isn’t in the GAC, and if there is no codeBase element, the CLR probes for the assembly. If the configuration file that performs the last redirection also contains a codeBase element, the CLR attempts to load the assembly from the codeBase element’s specified URL.
Publisher Policy Control
In the scenario described in the previous section, the publisher of an assembly simply sent a new version of the assembly to the administrator, who installed the assembly and manually edited the application’s or machine’s XML configuration files. In general, when a publisher fixes a bug in an assembly, the publisher would like an easy way to package and distribute the new assembly to all of the users. But the publisher also needs a way to tell each user’s CLR to use the new assembly version instead of the old assembly version. Sure, each user could modify his or her application’s or machine’s XML configuration file, but this is terribly inconvenient and error prone. What the publisher needs is a way to create policy information that is installed on the user’s computer when the new assembly is installed. In this section, I’ll show how an assembly’s publisher can create this policy information.
A publisher policy assembly is a way for a publisher to make a statement about the compatibility of different versions of an assembly. If a new version of an assembly isn’t intended to be compatible with an earlier version, the publisher shouldn’t create a publisher policy assembly. In general, use a publisher policy assembly when you build a new version of your assembly that fixes a bug. You should test the new version of the assembly for backward compatibility. On the other hand, if you’re adding new features to your assembly, you should consider the assembly to have no relationship to a previous version, and you shouldn’t ship a publisher policy assembly. In addition, there’s no need to do any backward compatibility testing with such an assembly.
.NET:CLR via C# Shared Assemblies and Strongly Named Assemblies的更多相关文章
- CLR via C# 3rd - 03 - Shared Assemblies and Strongly Named Assemblies
1. Weakly Named Assembly vs Strong Named Assembly Weakly named assemblies and strongly named ...
- Shared Assembilies and Strongly Named Assemblies
the .NET Framework has in place to deal with versioning problems. Two Kinds of Assemblies, Two Kinds ...
- Chapter 3 Shared Assemblies and Strongly Named Assemblies
As time marches on,MS developers and control developer modify their code:they fix bugs,patch securit ...
- SpringCloud报错:com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server
启动SpringCloudEureka 报错:com.netflix.discovery.shared.transport.TransportException: Cannot execute req ...
- .NET:CLR via C# Manifest
An assembly is a collection of one or more files containing type definitions and resource files. One ...
- 启动MongoDB时,提示:error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory
启动MongoDB时,提示: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: ...
- constant timer(固定定时器),constant throughput timer(常数吞吐量定时器);多个请求,某个请求a下,设置常数吞吐量定时器,模式:all active threads(shared)则所有请求吞吐量一致;
1.两请求之间添加'固定定时器' 1000ms,那么两请求发送间隔时间是多少? 1000ms吗? 由实验得出,2个请求发送间隔时间 = 1000ms + 第一个请求时间(发出至完成后时间) 2.单个请 ...
- linux下报错:error while loading shared libraries
linux执行bin程序报: error while loading shared libraries:libncurses.so.5: cannot open shared object file: ...
- 在eclipse中,Python项目遇到:…… from appium import webdriver ImportError: No module named appium
1) Traceback (most recent call last): File "D:\python workspace\src\p_test01\__init__.py" ...
随机推荐
- Codeforces 429C Guess the Tree(状压DP+贪心)
吐槽:这道题真心坑...做了一整天,我太蒻了... 题意 构造一棵 $ n $ 个节点的树,要求满足以下条件: 每个非叶子节点至少包含2个儿子: 以节点 $ i $ 为根的子树中必须包含 $ c_i ...
- Educational Codeforces Round 9 D - Longest Subsequence
D - Longest Subsequence 思路:枚举lcm, 每个lcm的答案只能由他的因子获得,类似素数筛搞一下. #include<bits/stdc++.h> #define ...
- 使用Generator(小黑鸟)反向生成Java项目(IDEA + Maven)
一.生成Maven项目 二.配置pom.xml文件 通用代码 <properties> <!-- 设置项目编码编码 --> <project.build.sourceEn ...
- Intellij IDEA Cannot resolve symbol XXX 问题解决办法汇总
maven项目遇到这类问题基本上是两方面的原因,类对应的依赖没有加载进来.编译器自身的设置和缓存问题. 解决第一类:1.检查项目的pom文件,是否必要的依赖都写清楚了: 2.是否使用自己的私有库,&l ...
- Java—String,StringBuffer,StringBuilde区别和操作
Java语言有关字符串的类有三种 java.lang.String:一般作为简单字符串类型 java.lang.StringBuffer:字符串缓冲区 java.lang.StringBuider:字 ...
- 【基础知识】Dom基础
[学习日记]Dom基础 1. 内容:使用JavaScript操作Dom进行DHTML开发 2. 目标:能共使用JavaScript操作Dom实现常见的DHTML效果 3. DHTML= C ...
- 【基础知识】JavaScript基础
[学习日记]JavaScript基础 1,一般写在<head></head>中(其实可以放到任意位置); 2,弹出对话框 <scripttype="text/j ...
- 配置k8s dns
DNS (domain name system),提供域名解析服务,解决了难于记忆的IP地址问题,以更人性可读可记忆可标识的方式映射对应IP地址. Cluster DNS扩展插件用于支持k8s集群系统 ...
- Python 随机数函数
random.random random.random()用于生成一个0到1的随机符点数: 0 <= n < 1.0 描述 random() 方法返回随机生成的一个实数,它在[0,1)范围 ...
- 机器学习之路: python 支持向量机 LinearSVC 手写字体识别
使用python3 学习sklearn中支持向量机api的使用 可以来到我的git下载源代码:https://github.com/linyi0604/MachineLearning # 导入手写字体 ...