Chair of Software Engineering
C# Programming in Depth
Prof. Dr. Bertrand Meyer
March 2007 – May 2007
Lecture 7: .NET Assemblies, Type Reflection
and Attribute-Based Programming
Lisa (Ling) Liu
How to create and deploy a .NET assembly library?
Build a Vehicle libary, which includes type Car, SportsCar and
MiniVan, UFO and Helicopter as one binary file or several binary
files?
Application-wide or machine-wide deployment?
Deploy the library on local machine or web?
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 2
How to build extendable applications?
Provide some input vehicle to allow the user to specify the module to
plug in
Determine if the module supports the correct functionality
Obtain a reference to the required infrastructure and invoke the
members to trigger the underlying functionality
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 3
Overview
Single-file and mutifile assemblies
Private and shared assemblies
Assembly configuration
Type reflection and late binding
Attribute-based programming
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 4
Assembly’s definition
.NET applications are constructed by piecing together
any number of assemblies.
An assembly (*.exe or *.dll) is a versioned, self-
describing binary file hosted by the CLR.
An assembly can be composed of multiple modules.
A module is a generic term for a valid .NET binary file.
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 5
The role of .NET assemblies
Promote code reuse
¾ reuse types in a language-independent manner
Establish a type boundary
Form versionable units
Provide type and composition information (self-
describing)
Facilitate deployment through configuration files
(configrable)
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 6
Format of a .NET assembly
A Win32 file header
A CLR file header
CIL code
Type metadata
An assembly manifest
Optional embedded resources
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 7
Class diagram of the Vehicle.dll assembly
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 8
Some questions you may ask
Do you want to use the same programming language to
implement the libray?
Do you want to allow client applications to download the
part of the library on demand?
Do you want to build the assembly as one binary file or
multiple binary files?
answer:
• same language, no, one binary file => Single file assembly
• different languages, yes, multiple binary files =>
Multifile assembly
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 9
Single-file and multifile assemblies
A single file assembly is exactly composed of a single
module
¾ Contains all of the necessary elements in a single *.exe
or *.dll
A multifile assembly is a set of .NET *.dlls that are
deployed and versioned as a single logic unit
¾ One of these *.dlls is termed the primary module and
contains the assembly-level manifest.
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 10
Single-file assemble
Manifest
Type Metadata
CIL Code
(Optional) Resourcses
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 11
Building and consuming a single-file assembly
You can use command-line compilers or Visual Studio
2005 to create a single-file assembly. By default, the
compiler creates an assembly file with an .exe extension
Visual studio automatically places a copy of the library
assembly into the directory of the client application
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 12
Multifile assemble
Primary module (*.dll)
*.netmodule
Manifest
(References other Type Metadata
related files)
CIL Code
Type Metadata
CIL Code *.netmodule
Type Metadata
CIL Code
*.bmp
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 13
Building and consuming a mutifile assembly
Build a mutifile assembly
1. Create secondary modules (*.netmodules)
csc.exe /t:module *.cs
2. Create primary module (*.dll)
csc.exe /t:library /addmodule:*.netmodule /out:*.dll
*.cs
Consume a mutifile assemble
¾ Supply onle the primary module to the compiler
csc /r: primary.dll client.cs
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 14
Benefits of multifile assemblies
Provide a very efficient way to download content
Enable modules to be authored using multiple .NET
programming languages
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 15
Deploy .NET assemblies
Private assemblies (Xcopy deployment)
¾ Private assemblies are required to be located in the
same directory as the client application
¾ Used to create an application-wide class library
Shared Assemblies
¾ A single copy of a shared assembly can be used by
several applications on a single machine
¾ Used to create machine-wide class library
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 16
Understanding private assemblies
Install a private assembly
¾ The identity of a private assembly
¾ The probing process
¾ Configuration of private assemblies
Uninstall a private assembly
¾ Delete the application folder
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 17
Identify a private assembly
The full identity of a private assembly is composed of
¾ The friendly name of the assembly
¾ The numerical version of the assembly
The assembly manifest record the identity of the private
assembly
.assembly Vehicle
{
...
.ver 1:0:0:0}
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 18
Probe a private assemble
Probing is the process of mapping an external assembly
request to the location of the requested binary file
Implicit probing
Explicit probing
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 19
Configure private assemblies
*.exe.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="lib"/>
</assemblyBinding>
</runtime>
</configuration>
• Instruct CLR to probe the subdirectories within client application
directory
• Has the same name as the launching application and take a *.config
file extension
• Must be deployed in the application directory
• Use the privatePath attribute to set the probing subdirectory
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 20
Understanding shared assemblies
Install a shared assembly
¾ Strongly name a shared assembly
¾ Install the shared assembly into the Global Assembly
Cache (GAC)
Uninstall a shared assembly
¾ Use command-line utility gacutil.exe to uninstall a
shared assembly
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 21
Strong name
A strong name is a unique identifier of an assembly
A strong name is based on two cryptographically related
keys (public key and private key).
A strong name consists of following data:
¾ The friendly name of the assembly
¾ The version number of the assembly (assigned using
the [AssemblyVersion] attribute)
¾ The public key value (assigned using the
[AssemblyKeyFile] attribute)
¾ An optional culture identifier value for localization
purpose (assigned using the [AssemblyCulture]
attribute)
¾ An embedded digital signature created using a hash of
the assembly’s contents and the private key value
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 22
Generate digital signature at compile-time
*.dll
Manifest
(with public key)
Assembly Private Key Digital
+ =
Type Metadata Hash Code Data Signature
CIL Code
digital signature
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 23
Strongly naming an assembly
1. Create the required key data using sn.exe
sn –k MyTestKey.snk
2. Inform the C# compiler where the MyTestKey.snk is
located
[Assembly:
AssemblyKeyFile(@”C:\MyTestKey\MyTestKey.snk”)]
3. Specify the version of a shared assembly
A .NET version is composed of the four parts:
<major>.<minor>.<build>.<version>
[Assembly: AssemblyVersion(“1.0.*”)]
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 24
Install a shared assembly to the GAC
Global Assembly Cache (GAC) is located under the
Assembly subdirectory (C:\Windows\Assembly) under
your windows directory
Install a shared assembly to the GAC by dragging or
dropping the assembly to C:\Windows\Assembly
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 25
gacutil.exe
/i Install a strongly name assembly into the GAC
/u Uninstall an assembly from the GAC
/l Displays the assemblies (or a specific assembly) in
the GAC
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 26
Delayed signing
Install an assembly into the GAC for testing purpose
The administrator or some trusted individual that holds
the *.snk file extracs the public key value from the *.snk
file
sn.exe –p myKey.snk testPublicKey.snk
Distribute the extracted testPublicKey.snk to developers
The developer specifies the delayed signing attribute in
the assembly
[Assembly: AssemblyDelaySign(true)]
[Assembly:
AssemblyKeyFile(@”C:\MyKey\testPublicKey.snk”)]
Disable the signature verification process when deploying
an assembly to GAC
sn.exe –Vr MyAssembly.dll
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 27
After delayed signing ...
Ship the assembly to the trusted individual who holds
the “true” public/private key file
The trusted individual Resigns the assembly to provide
the correct digital signature
sn.exe –R MyAssembly.dll C:\MyKey\myKey.snk
Enable the signature verification procedure
sn.exe –Vu MyAssembly.dll
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 28
Consuming a shared assembly
In Visual Studio 2005, you must reference shared
assemblies by navigating to the project’s \Bin\Debug
directory
The Copy Local property can force a copy of a strongly
named code library
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 29
Configure shared assemblies
Build ClientApplication.exe.config file to instruct CLR to
bind to the assembly with required version number
Set bindingRedirect attribute of dependentAssemble
element to the required version number
Dynamic updating library
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 30
Publisher policy assemblies
With Publisher policy assemblies, client applications need
not to set specific *.config files
CLR performs the request redirection at the level of
GAC
Create publisher policy assemblies using al.exe command
al.exe /link: CarLibraryPolicy.xml
/out:policy.1.0.CarLibrary.dll
/keyf:C:\MyKey\MyKey.snk /v:1.0.0.0
Disable publisher policy
¾ Build specific client application configuration file and
set the apply attribute of element publisherPolicy as
“no”
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 31
<codeBase> element
The <codeBase> element is used to instruct the CLR to
probe for dependent assemblies located at arbitrary
locations
It can be used to download asseblies from a given URL
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 32
The System.Configuration namespace
The System.Configuration namespace allows programmers
to programmatically read the data within a client
configuration file
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 33
The machine configuration file
machine.config file
¾ It contains machinewide application settings (via an
<appsetting> element)
¾ .NET platform maintains a separate *.config file for
each version of the framework installed on the local
machine
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 34
How to build extendable applications?
Provide some input vehicle to allow the user to specify the module to
plug in (Dynamic loading)
Determine if the module supports the correct functionality (Type
reflection)
Obtain a reference to the required infrastructure and invoke the
members to trigger the underlying functionality (Late binding)
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 36
Type reflection
In the .NET universe, reflection is the process of
runtime type discovery
System.Reflection namespace
¾ Assembly, AssemblyName, EventInfo, FieldInfo,
MethodInfo, ParameterInfo and PropertyInfo
System.Type class
¾ GetConstructors(), GetEvents(), GetFields(),
GetInterfaces(), GetMembers(), GetMethods(),
GetProperties(), InvokeMember()
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 37
Reflect the type information
Obtain a type reference using System.Type.GetType()
Type t = Type.GetType (typeName);
Reflecting on methods
MethodInfo[] mi = t.GetMethods();
Reflecting on Fields and properties
FieldInfo[] fi = t.GetFields();
PropertyInfo[] pi = t.GetProperties();
How to reflect the type defined in an
assembly not known at compile time?
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 38
Dynamically loading assemblies
Dynamic load
The act of loading external assemblies on demand
Use methods Load() or LoadFrom() defined in class
Assembly to dynamically load an assembly (private or
shared assembly)
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 39
Reflect on shared assemblies
To load a shared assembly from the GAC, the
Assembly.Load() must specify a publickeytoken value
Two ways of specifying a publickeytoken when loading a
shared assembly
Assembly a = Assembly.Load(@”System.Windows.Forms,
PublicKeyToken=b77a5c561934e089”)
AssembleyName asmName;
asmName = new AssemblyName();
asmName.SetPublicToken(byte[]);
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 40
Late binding
Late binding is a technique in which you are able to
create an instance of a given type and invoke its
members at runtime without having compile-time
knowledge of its existence
Assembly a = Assembly.Load(“CarLibrary”);
Type miniVan = a.GetType (“CarLibrary.MiniVan”);
object obj = Activator.CreateInstance(miniVan);
MethodInfo mi = miniVan.GetMethod(“TurboBoost”);
mi.Invoke(obj, null);
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 41
Attributed programming
Using attributes, programmers can embed additional
metadata into an assembly
.NET attributes are class types that extend the abstract
System.Attribute base class
Attribute consumers
¾ C# compiler
¾ Numerous methods in the .NET base class libraries,
for example, Serialize()
An attribute is only applied to the “very next” item
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 42
Predefined attributes in C#
[CLSCompliant]
[DllImport]
[Obsolete]
[Serializable]
[NonSerialized]
[WebMethod]
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 43
Building custom attributes
public sealed class VehicleDescriptionAttribute: System.Attribute
{
private string msgData;
public VehicleDescriptionAttribute (string description)
{msgData = description;}
public vehicleDescriptionAttribute() {}
public string Description
{
get {return msgData;}
set {msgData = value;}
}
}
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 44
Assembly-level attributes
Apply attributes on all types within a given module or all
modules within a given assembly using the [module:] and
[assembly:]
[assembly: System.CLSCompliantAttribute(true)]
Visual studio 2005 AssemblyInfo.cs file
A handy place to put attributes that are to be applied at
the assembly level
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 45
Questions?
C# programming lecture 7: .NET assembly, type reflection and attribute-based
programming 46