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的更多相关文章

  1. 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 ...

  2. Shared Assembilies and Strongly Named Assemblies

    the .NET Framework has in place to deal with versioning problems. Two Kinds of Assemblies, Two Kinds ...

  3. 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 ...

  4. SpringCloud报错:com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server

    启动SpringCloudEureka 报错:com.netflix.discovery.shared.transport.TransportException: Cannot execute req ...

  5. .NET:CLR via C# Manifest

    An assembly is a collection of one or more files containing type definitions and resource files. One ...

  6. 启动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: ...

  7. constant timer(固定定时器),constant throughput timer(常数吞吐量定时器);多个请求,某个请求a下,设置常数吞吐量定时器,模式:all active threads(shared)则所有请求吞吐量一致;

    1.两请求之间添加'固定定时器' 1000ms,那么两请求发送间隔时间是多少? 1000ms吗? 由实验得出,2个请求发送间隔时间 = 1000ms + 第一个请求时间(发出至完成后时间) 2.单个请 ...

  8. linux下报错:error while loading shared libraries

    linux执行bin程序报: error while loading shared libraries:libncurses.so.5: cannot open shared object file: ...

  9. 在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" ...

随机推荐

  1. google浏览器打开新的标签页显示http://www.google.com.hk/url?sa=p&hl=zh-CN&……

    chrome的版本:51.0.2704.106 m使用该版本的chrome后,每次打开新标签页,都会提示“无法访问此网站”.并自动跳转到一个地址“http://www.google.com.hk/ur ...

  2. Kylin使用笔记-1: 安装

    2016年1月14日 9:57:23 星期四 背景介绍     Apache Kylin是一个开源的分布式分析引擎,提供Hadoop之上的SQL查询接口及多维分析(OLAP)能力以支持超大规模数据,最 ...

  3. Codeforces Round #334 (Div. 1) B. Moodular Arithmetic

    B - Moodular Arithmetic 题目大意:题意:告诉你p和k,其中(0<=k<=p-1),x属于{0,1,2,3,....,p-1},f函数要满足f(k*x%p)=k*f( ...

  4. thinkphp调整框架核心目录think的位置

    thinkphp的核心目录即框架文件可以放在项目之外的目录,这点手册上有提到,放在项目之外的地方可以方便其他项目共用一个框架文件. 在入口文件的index.php中,在导入框架目录这一行,可以直接修改 ...

  5. CSUOJ 1808 地铁

    Description Bobo 居住在大城市 ICPCCamp. ICPCCamp 有 n 个地铁站,用 1,2,-,n 编号. m 段双向的地铁线路连接 n 个地铁站,其中第 i 段地铁属于 ci ...

  6. 历史文章分类汇总-Anaconda安装第三方包(whl文件)

    本文主要是对公众号之前发布的文章进行分类整理,方面大家查阅,以后会不定期对文章汇总进行更新与发布.   一.推荐阅读: Anaconda安装第三方包(whl文件) 福布斯系列之数据分析思路篇 福布斯系 ...

  7. 深入理解python中的select模块

    简介 Python中的select模块专注于I/O多路复用,提供了select  poll  epoll三个方法(其中后两个在Linux中可用,windows仅支持select),另外也提供了kque ...

  8. 【BFS】【最小生成树】Petrozavodsk Winter Training Camp 2018 Day 1: Jagiellonian U Contest, Tuesday, January 30, 2018 Problem G. We Need More Managers!

    题意:给你n个点,点带权,任意两点之间的边权是它们的点权的异或值中“1”的个数,问你该图的最小生成树. 看似是个完全图,实际上有很多边是废的.类似……卡诺图的思想?从读入的点出发BFS,每次只到改变它 ...

  9. hash课堂测试补分博客

    题目要求: 开放地址法: 概念: 所谓的开放定址法就是一旦发生了冲突,就去寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找到,并将记录存入. 它的公式为: 解题过程(在下图中): 拉链法: ...

  10. [CodeChef-QUERY]Observing the Tree

    题目大意: 给你一棵树,一开始每个点的权值都是0,要求支持一下三种操作: 1.路径加等差数列. 2.路径求和. 3.回到以前的某次操作. 强制在线. 思路: 树链剖分+主席树. 最坏情况下,n个点的树 ...