Overview :
This article talks about the assembly and types of assembly in CSharp / C#. Here, We will discuss What is GAC [Global Access Cache] and how does it solve DLL Hell problem. we will also cover the strong name concept and how to add an assembly in GAC.
Let’s start the discussion :
What is assembly?
In .net, an assembly is bundled of all the compiled code and resources of the application. It contains all the reference of the resources used in the application. When we build any .net project, assembly gets created which contains all the compiled code and linked resources such as files, image etc. An assembly can contain one or more assembly.
Manifest in assembly:
Assembly is self-describing, means it has all the metadata information about everything an application uses, such as class, method, external DLLs. All these metadata are stored in assembly as a block, called Manifest.
The difference from COM:
As all information is contained in assembly, it is not dependent on the registry. This is the basic advantage when this compared to COM where the version is stored in the registry.
Types of assembly :
Private assembly:
A private assembly is used by only one application.
For private assembly deployment, the assembly is copied to the same directory as the client program which references it. No registration and no installation is required. When the component is removed, no registry need to clean up and no uninstallation is needed. Just needed to delete from hard disk.
Public assembly/Shared assembly:
Assembly which is used by multiple application in the machine. In such a case, we need to keep this public assembly in the commonplace, so multiple application can use the same assembly. This commonplace is called GAC [Global Access Cache].
What is GAC [Global Access Cache]
GAC is a common container to store all the public assembly which is used by one or more different application.
Unlike COM component, In case of shared assembly, we can keep multiple version of same assembly side by side in GAC without effecting client applications which use the previous version of the assembly. This is possible because of strong name identity to each version of the assembly.
Strong Name :
A strong name is a unique identifier[public key token] which makes assembly(DLL or EXE) unique. An assembly name consists of 5 parts :
- Assembly Name: Any Name
- Version Name: version name
- Cultural information: en-US, etc
- Public key token: alphanumeric
- Processor: processor architecture, x64
All the assembly with Public key token(strong name) is called Strong Named Assembly. Only strongly typed assembly is allowed to keep in GAC. Strongly Named Assembly are guaranteed to be unique and solved DLL hell problem.
Steps to generate a strong name and signed the assembly:
1. Create Strong Name using SN.exe:
- Open command prompt
- sn.exe -k c:\mystrong.snk
2. Signed assembly with SN.exe
- In AssemblyInfo.cs, add [assembly: AssemblyKeyFile(“C:\MyStrong.snk”)]
- Build the project.
3. Copy assembly to GAC :
We can directly copy the assembly to the GAC location or install using GACUtil.exe.
- Direct copy to GAC Location:
Different version of .net has different gac location
– Before 4.0 – C\Windows\assembly
– After 4.0 – C\Windows\Microsoft.NET\assembly.
- Copy Using GAC Utitlity :
-
- adding to GAC: gacutil -i ‘path of stronged name assembly’
-
- Removing from GAC: gacutil -u classLibrary
We can also specify other properties of assembly while removing from GAC.
gacutil -u classLibrary, Version=1.0.0.1, PublicKeyToken = eeaafd23df…
What is DLL Hell Problem and how does GAC solve it :
Earlier, With COM component, It was not possible to keep the multiple version of the component/dll in the same directory.
Old version component was getting replaced with new version component because of the same signature.
In result, the application which refers to the old version of the component, getting affected.
For example,
Application A refers to Component C1 which has a method of M1() with one parameter. Application B using the same but updated component C1 with method M1() with 2 parameters.
So, when we install application B, it replaces the old C1 component with new C1. But, now application A will not be work as the method M1() have 2 parameters. This is called DLL Hell problem.
Using a strong name, each assembly is unique, and Old and New version of assembly can be sit side by side in the GAC. So, With this, the old assembly is not getting updated by the new version of the assembly, hence the application which refers to the old assembly, would not get affected anyway.
Conclusion:
We discussed the assembly, GAC, strong names and how does it solve DLL Hell problem.
References: https://docs.microsoft.com/en-us/dotnet/framework/app-domains/gac