0% found this document useful (0 votes)
23 views36 pages

Understanding .NET Assemblies and Modules

Assemblies in the .NET Framework are the fundamental units for packaging and distributing executable code, containing type definitions and access modifiers that control visibility. They consist of one or more modules, which are physical files that may be compiled using different programming languages. Assemblies utilize public-key technology for identification and tamper prevention, and they can be loaded and resolved through various methods, including explicit URLs and version policies.

Uploaded by

api-3775463
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
23 views36 pages

Understanding .NET Assemblies and Modules

Assemblies in the .NET Framework are the fundamental units for packaging and distributing executable code, containing type definitions and access modifiers that control visibility. They consist of one or more modules, which are physical files that may be compiled using different programming languages. Assemblies utilize public-key technology for identification and tamper prevention, and they can be loaded and resolved through various methods, including explicit URLs and version policies.

Uploaded by

api-3775463
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Assemblies

Peter Drayton
peter@[Link]

1
Assemblies and the .NET Framework

• The Common Language Runtime requires all types to belong to


an assembly. Assemblies act as the smallest distribution unit for
component code in the .NET Framework.

2
Assemblies defined

• Assemblies are used to package and distribute executable code


– Assemblies are the atom of deployment in the CLR
– Assemblies are collections of type definitions
– Type names are scoped by their containing assembly
– Only types and members marked public are visible outside
the assembly
– internal members and types inaccessible outside of
assembly
– private members inaccessible outside of their declaring
type

3
Figure 1: Access modifiers

C# [Link] Meaning

public Public Type is visible everywhere


Type
internal Private Type is only visible inside of assembly
public Public* Member is visible everywhere
Member internal Friend Member is only visible inside of assembly
private Private* Member is only visible inside of declaring type

* [Link] defaults to Public for methods and Private


for fields declared using the Dim keyword

4
Assemblies and modules

• An assembly consists of one or more physical files known as


modules
– A module is an executable file containing code and metadata
– Each module may be produced using different programming
languages
– Exactly one module in an assembly contains an assembly
manifest
– [Link]'s /t:module and /addmodule switches support
module-level compilation/references
– The assembly linker [Link] can link multiple modules and
create the manifest

5
Figure 2: Modules and Assemblies

/t:module /t:library
.module [Link] .module [Link]
.assembly extern mscorlib .assembly extern mscorlib
.assembly extern paul .assembly extern paul
.class public PP { .class public PP {
.field [paul]Bassist m .field [paul]Bassist m
} }
.assembly pete Manifest

6
Figure 3: A multi-module assembly

/t:library /addmodule:[Link],[Link]
.module [Link] /t:module
.assembly extern mscorlib .module [Link]
.assembly extern paul
.assembly extern john .assembly extern mscorlib
.assembly extern paul
.class public Manager {
} .class public PP {
.field [paul]Bassist m
.assembly band }
.file [Link] /t:module
.file [Link]
.module [Link]
Manifest

.class extern public GP


{.file [Link] .assembly extern mscorlib
.class nnnn } .assembly extern john
.class extern public PP .class public GP {
{.file [Link] .field [john]Singer m
.class nnnn } }

7
Figure 4: Multi-module assemblies using [Link]

Component Assembly

[Link] [Link] /t:module [Link]

[Link] /t:library
[Link] [Link]
/addmodule:[Link]

Application Assembly

[Link] csc /r:[Link] [Link]

8
Figure 5: Multi-module assemblies using [Link] and NMAKE

# [Link] cannot be loaded as is until an assembly


# is created
[Link] : [Link]
csc /t:module [Link]

# types in [Link] can see internal and public members


# and types defined in [Link]
[Link] : [Link] [Link]
csc /t:library /addmodule:[Link] [Link]

# types in [Link] cannot see internal members and


# types defined in [Link] (or [Link])
[Link] : [Link] [Link]
csc /t:exe /r:[Link] [Link]

9
Public Keys and Assemblies

• Assemblies use public-key technology both to identify the


developer and to prevent tampering
– Cryptographic signature based on public/private key pair
– Cannot tamper with assembly without resigning
– Originator in target assembly contains complete 1024-bit
RSA public key
– Originator in assembly reference contains 64-bit hash of full
public key
– The [Link] tool manages public/private key files
– The AssemblyKeyFile and AssemblyDelaySign
attributes associate keys with assemblies

10
Figure 6: Managing public/private keys using [Link]

[Link] -k [Link]

Public Key
Private Key
[Link] (128 bytes + 32
(436 bytes)
byte header)

[Link] -p [Link] [Link]

Public Key
[Link] (128 bytes + 32
byte header)

[Link] -t [Link]

Public key token is 883dd0182e81d815

11
Figure 7: Strong assembly references

[Link]
[Link]
using [Link];
Public Key
[assembly: AssemblyKeyFile("[Link]")]
(128 bytes + 32
[assembly: AssemblyDelaySign(false)] byte header)

csc /t:library [Link] Private Key


(436 bytes)
[Link]
Public Key
(128 bytes + 32 Signature
byte header)
PE/COFF
Header CLR Header Code

[Link]
mylib
Public Key Token (8 bytes)
Assembly Reference
PE/COFF
Header CLR Header Code

12
Figure 8: Delay signing an assembly

[Link]
using [Link];
[assembly: AssemblyKeyFile("[Link]")]
[assembly: AssemblyDelaySign(true)]
[Link]
Public Key
csc /t:library [Link] (128 bytes + 32
byte header)
[Link]
Public Key Space
(128 bytes + 32 For [Link]
byte header) Signature Public Key
PE/COFF (128 bytes + 32
Header CLR Header Code byte header)

Private Key
sn -R [Link] [Link] (436 bytes)
[Link]
Public Key
(128 bytes + 32 Signature
byte header)
PE/COFF
Header CLR Header Code

13
Assembly names

• All assemblies have a four-part name that uniquely identifies the locale
and developer of the component
– The simple Name typically corresponds to the file name (no
extension)
– The Version identifies the major/minor/build/revision numbers
– The (optional) CultureInfo corresponds to language and region
– The (optional) Originator/PublicKey identifies the developer
– Display names are stringified assembly names suitable for human
entry
– Note: Namespace prefixes of types may or may not match the
Name of the assembly

14
Figure 9: Inside the AssemblyVersion attribute

Attribute Actual
Parameter Value
1 [Link]
1.2 [Link] * where d is the
number of days
1.2.3 [Link] since Feb. 1, 2000
[Link] [Link] and s is the
number of seconds
1.2.* 1.2.d.s since midnight /2
1.2.3.* 1.2.3.s
<absent> [Link]

15
Figure 10: Fully specified assembly names

Display Name of Assembly Reference


yourcode, Version=[Link], Culture=en-US, PublicKeyToken=1234123412341234
or neutral or null
C# Code

using [Link];
[assembly: AssemblyVersion("[Link]") ]
[assembly: AssemblyCulture("en-US") ] // resource-only assm
[assembly: AssemblyKeyFile("[Link]") ]

16
Loading and resolving assemblies

• Assemblies can be loaded either by an explicit URL or a four-part


assembly name
– [Link] loads an assembly based on an explicit
CODEBASE (e.g., a file name or URL)
– [Link] first uses the assembly resolver to resolve a 4-
part assembly name to a file prior to loading
– Subordinate assemblies always loaded using assembly resolver
– Subordinate modules and assemblies only loaded on demand
– CODEBASE hints specified using per-application/machine
configuration files
– Assemblies from non-file URLs are cached in the download cache
(watch out for SecurityException from untrusted code)

17
Figure 11: Loading an assembly with an explicit CODEBASE

using System;
using [Link];

public static Object LoadCustomerType() {


Assembly a = [Link](
"[Link]
return [Link]("[Link]");
}

18
Figure 12: Assembly resolution and loading

[Link](name,culture,version,token) [Link]

APPBASE <bindingRedirect>

POLICY <codeBase>
Assembly
Resolver
CODEBASE <probing>

PRIVATE_BINPATH

Assembly
Loader

Loaded Assembly

19
Figure 13: Loading an assembly using the assembly resolver

using System;
using [Link];

public static Object LoadCustomerType() {


Assembly a = [Link](
"xyzzy, Version=[Link], " +
"Culture=en-UK, PublicKeyToken=9a33f27632997fcc");
return [Link]("[Link]");
}

20
Version policy

• The assembly resolver can map the requested version of an


assembly to a newer (or older) one via configured version
policies
– Only applies to fully-specified assembly references (name,
version, culture, publickey)
– Only applies when the assembly resolver is used
– Applied before any other actions are taken by the resolver
– Specified via configuration files per application and machine-
wide

21
Figure 14: Assembly resolver configuration file format

configuration
0..1 Element (xmlns="") Attribute

runtime Element (xmlns="urn:[Link]:asm.v1")


0..1

assemblyBinding

0..N 0..1 0..1

dependentAssembly probing publisherPolicy

privatePath apply

name
assemblyIdentity publicKeyToken
0..1
culture

0..N version
codeBase
href

0..N oldVersion
bindingRedirect
newVersion

0..1
publisherPolicy apply

22
Figure 15: Setting the version policy

<?xml version="1.0" ?>


<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

<!-- one dependentAssembly per unique assembly name -->


<dependentAssembly>
<assemblyIdentity
name="[Link]"
publicKeyToken="38218fe715288aac" />

<!-- one bindingRedirect per redirection -->


<bindingRedirect oldVersion="[Link]"
newVersion="[Link]“ />
<bindingRedirect oldVersion="1-[Link]"
newVersion="[Link]" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

23
Figure 16: Setting the application to safe-mode

<?xml version="1.0" ?>


<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<publisherPolicy apply="no"/>
</assemblyBinding>
</runtime>
</configuration>

24
The assembly cache

• Assemblies are first loaded from the machine-wide assembly


cache
– The assembly cache makes assemblies available
independent of where the application is located
– The download cache holds assemblies loaded from non-file-
based URL
– The global assembly cache (GAC) holds system-level
assemblies
– The assembly resolver always consults the GAC first
– The GAC is a secured resource and requires admin
privileges to add/delete entries
– The GAC only contains signed assemblies with public keys

25
Figure 17: Global Assembly Cache

Public Key Mangled


Name Version Culture
Token Path
yourcode [Link] de 89abcde... t3s\e4\[Link]
yourcode [Link] en 89abcde... a1x\bb\[Link]
yourcode [Link] en 89abcde... vv\a0\[Link]
libzero [Link] en 89abcde... ig\u\[Link]

26
Assembly resolving via CODEBASE or probing

• If the assembly cannot be found in the GAC, the assembly


resolver tries to use a CODEBASE hint to access the assembly
– Configuration files can/should provide a CODEBASE hint
– If matching file not accessible via provided CODEBASE
URL, Load fails
– If no hint is provided, the assembly resolver must probe
several location
– Relative search path uses subdirectories of the APPBASE
– Probe path can be augmented using configuration files
– Resultant assembly must match all specified properties (e.g.,
(policy-adjusted) version, culture)

27
Figure 18: Specifying the codebase using configuration files

<?xml version="1.0" ?>


<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

<!-- one dependentAssembly per unique assembly name -->


<dependentAssembly>
<assemblyIdentity name="[Link]"
publicKeyToken="38218fe715288aac"/>

<!-- one codeBase per version -->


<codeBase version="[Link]"
href="[Link]
<codeBase version="[Link]"
href="[Link]
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

28
Figure 19: APPBASE and the relative search path

m
[Link]
(APPBASE)
C:\
n o q
Eligible Ineligable
Directories Directories p
C:\m C:\
C:\m\o C:\n
C:\m\o\q
C:\m\p

29
Figure 20: Setting the relative search path

<?xml version="1.0" ?>


<configuration>
<runtime>
<assemblyBinding
xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="shared;aux" />
</assemblyBinding>
</runtime>
</configuration>

30
Figure 21: Culture-neutral probing

Assembly Reference Potential CODEBASEs (in order)

yourcode, Culture=neutral,... [Link]


[Link]
APPBASE [Link]
[Link]
[Link] [Link]
[Link]
Application Configuration File
[Link]
<configuration xmlns:asm="...">
[Link]
<runtime>
[Link]
<asm:assemblyBinding>
[Link]
<asm:probing
[Link]
privatePath="shared;aux" />
[Link]
</asm:assemblyBinding>
</runtime>
</configuration>

31
Figure 22: Culture-dependent probing

Assembly Reference Potential CODEBASEs (in order)

yourcode, Culture=en-US,... [Link]


[Link]
APPBASE [Link]
[Link]
[Link] [Link]
[Link]
Application Configuration File
[Link]
<configuration xmlns:asm="...">
[Link]
<runtime>
[Link]
<asm:assemblyBinding>
[Link]
<asm:probing
[Link]
privatePath="shared;aux" />
[Link]
</asm:assemblyBinding>
</runtime>
</configuration>

32
Figure 23: Assembly resolution
Apply Version Policy
(if reference fully specified)

Match already Use assembly


Y
loaded? already loaded
N

Match in Use file found in


Y
Global Cache? Global Cache
N

Is file found
<codeBase> N
N via probing?
hint provided?
Y
Y

Does file match


N
[Link] N
Does file match
reference? Fails reference?
Y Y

Use file found at Use file found


CODEBASE from probing

33
Versioning hazards

• Loading multiple versions of the same assembly is not without


risks and problems
– The CLR treats same-named types as distinct when they
come from different physical assemblies
– One copy of global/static variables per version
– Types from V2 cannot be passed where types defined in V1
are expected
– Putting globals/static variables in a non-versioned assembly
addresses the former
– Avoiding using versioned types as parameters addresses
the latter

34
Summary

• The assembly is the "component" of the CLR


• All types belong to exactly one assembly
• Assemblies carry a digital signature from the developer who
created them
• Assemblies support multiple versions loaded simultaneously in
the same program
• Assemblies can be automatically downloaded from the Internet

35
Questions?

36

You might also like