GAC Registration

You want to know the pros and cons of registering your DLL assemblies in the GAC.

The pros of registering are 1. The .NET runtime finds GAC assemblies more quickly and loads them faster because it doesn’t have to check their integrity. 2. Assemblies in the GAC are protected from accidental deletion because only an administrator can access the GAC directory. The cons of registering are 1. More complicated deployments since you can’t rely on XCOPY to automatically register the assembly for you. 2. Having to uninstall the previous version from the GAC each time you recompile.

You don’t want to use the GAC if your sole purpose is to share types among different applications; there are better ways to accomplish this goal. You can share an assembly, including private ones, among different applications if all applications’ executable files are deployed in the same directory. Or, using a different approach, you can reference a strong-named assembly that is located outside the application’s main directory by using the element in the application’s configuration file.

Additional details
There are ways to make GAC registration simpler. There’s a utility named Gacutil that comes with the Windows SDK and is automatically installed with Visual Studio. If you’re not a Visual Studio user like me, you can simply get it with the Windows SDK. You can configure Gacutil to run as a post-build event. In Visual Studio, you can configure the command to run in the Project Properties dialog box. Otherwise, you can add it to the .csproj file like so:

<Target Name="AfterBuild">
    <Exec Command="Path to SDK\...\Gacutil.exe" /i $(TargetPath)" Condition="" />

Culture Attribute for Main Assembly

You want to know the best way to mark your main assembly for a given locale.

Use the NeutralResourcesLanguage attribute on the main assembly. This will inform the resource manager about the language for neutral resources that are embedded in the main assembly.

Using this attribute speeds up resource loading when the current user’s locale matches the culture used for resources in the main assembly. Don’t use the AssemblyCultureAttribute in the main assembly. The main assembly should only contain neutral resources (for example, strings and images related to the default language).


// This particular assembly contains resources for the US English culture.
[assembly: NeutralResourcesLanguage("en-US")]

Resources in .Resx Files

You want to know the benefits of using resource (.resx) files.

Resource files provide a simple way to localize your .NET applications by automatically determining the .resx file to use based on a user’s locale. In addition, resource files provide a central location to store strings, files, and other scripts that can be referenced in a strongly-typed way. Another advantage is they can be compiled into satellite assemblies, making them easier to modify in a production environment.

String resources are great for error messages and user interface elements. Use them for human-readable text and not constants to be accessed programmatically.

Resource Names

You want to know the recommended naming convention for resources.

Use PascalCase for resource names. In general, you’ll want to follow the same guidelines you use when naming public fields.
1. Use descriptive names.
2. Don’t include spaces or punctuation marks.
3. Don’t start the name with a digit.
4. Avoid keyword names like long.

For example, ChromeDriver is a good resource name, whereas chromeDriver and Chrome:Driver aren’t. In addition, feel free to include dots to specify the property of an object (e.g. lblSearch.Text) or to separate elements in a hierarchy, such as Menus.Edit.Reformat.Text.

Manifest Resources vs. Stand-Alone Files

You want to know when and how to embed resources in your project.

You should favor using embedded resources for read-only data that will never change during your application’s lifetime. Use separate files to store data that the application can change or that you may want to deploy independently of the main application.

Pros & Cons
Resources that are embedded in the main assembly’s manifest can be located and loaded faster. They are also protected from accidental deletion. This technique is not best used when you have resources that are locale-dependent and should be localized for each language you support.

You can embed any data file in the assembly’s manifest by following these steps:
1. Add the file to the project.
2. Right-click the file and choose Properties.
3. Set the Build Action to Embedded Resource.

The following code demonstrates how to programmatically access a text file named TestData.txt from inside an assembly whose default (root) namespace is TestAutomation.

string dataFile = "TestAutomation.TestData.txt";
// Get a reference to the assembly.
Assembly assembly = Assembly.GetExecutingAssembly();
Stream stream = assembly.GetManifestResourceStream(dataFile);
// Read the contents of the embedded file and close it.
StreamReader reader = new StreamReader(stream);
string text = reader.ReadToEnd();

Assembly Versioning

You want to know how to version your assemblies and any potential pitfalls.

Edit the AssemblyVersion(“”) attribute in the AssemblyInfo.cs file, and give the assembly a specific version number. Change the version number when you publish a new version of the assembly.

Specifying a version number is important because it gives the assembly a strong name. One gotcha: If you use an asterisk in the version number, the version number changes each time you recompile the assembly. As a result, all client assemblies have to be recompiled and the identity of any enclosed types will change. Further, this will lead to problems when deserializing an object that was serialized by a previous version of the same assembly.


// Incorrect. Uses an asterisk.
[assembly: AssemblyVersion("1.0.*")]

// Correct. Remember to change as needed.
[assembly: AssemblyVersion("")]

Multi-module Assemblies

You have more than one module and are considering merging it as one assembly. Should you do it?

Avoid multi-module assemblies. In most cases, you can deploy an application as one main EXE plus zero or more DLLs without creating multi-module assemblies.

Compiling multi-module assemblies requires using the Al.exe command-line tool, and this slows down the build process. The main advantage of having a single assembly composed of multiple modules rather than multiple distinct assemblies is that types marked as internal are visible to types in other modules. If you have distinct assemblies, you must mark these types public to make them callable by another assembly. However, in this scenario, you can’t easily prevent other assemblies from using your types. Multi-module assemblies are required when you have to merge modules written in different languages into one assembly. But, in such cases, you should consider splitting the application into distinct assemblies (one per language).

Size of Assemblies

You want to know how large your assemblies should be.

In general, prefer few large assemblies to many smaller ones. If you have a group of types that are always loaded and used together, place them in the same assembly. If you have two or more assemblies that are always loaded and used together, merge them into a single assembly.

The .NET runtime loads a large assembly faster than several smaller ones. A single, larger assembly creates a smaller working set of the application, and Ngen.exe can optimize it more effectively. On the other hand, you may need to split a larger assembly into several smaller ones if the types in it need to be assigned different identities or trust levels.