Design Guidelines Update: Resources

We just added some new design guidelines related to naming and usage of resources. Enjoy.


Resources can be used in libraries to store error messages, labels, and icons. MSDN article Resources and Localization Using the .NET Framework SDK is a good source of background information on the .NET Framework resource model.

There are two models developers can use when they organize their resources. The first one is to have all the resources including the neutral resources in satellite assemblies and make the main assembly resources-free. The second model is to put the neutral resources in the main assembly and put the rest of resources in satellite assemblies.

Annotation (Ahmed AbouTaleb):

The first model described above –All resources in satellites- is not supported in V1.0 and V1.1.


            Do not hardcode strings in your source code, store all strings in resources1.

string errorMsg = “File not found. Please check the path.”;

This code is hard to localize because the string is inside the code and the only way to localize it is by providing an executable for each culture.


string errorMsg = resourceManager.GetString(“FileNotFound”);

This code is easier to localize and storing all the messages in the resources decouple them from the source code. Also, creating satellite assemblies for your localized resources will make it easier to support more languages in the future.


*      Do store all resources including the neutral resources in satellite assemblies. This way it is easier to localize, easier to setup and faster to load or download if it is a downloadable library.

Note: You may need to consider putting the neutral resources in the main assembly in some situations where your neutral language is the one that will be used by most of your customers.

*      Do create satellite assemblies with the .resources in the name of the assembly like “MyLibrary.resources.dll” for a main assembly named “MyLibrary.dll”.


            Do not set the culture in the main assembly. Main assembly is used for code and it should contain the neutral resources only.

To have a culture-neutral assembly don’t add culture attribute to your assembly and don’t set culture in the linker when generating the main assembly. For example don’t do any of the following.

[assembly:AssemblyCultureAttribute(“en”)]// Setting the culture to English

al /out:MyLibrary.DLL /embed:ErrorStrings.resources /culture:en


            Do not insert the culture name in manifest resource names in the main assembly.

The main assembly contains the neutral language resources and those resources should be culture-neutral. The name of the manifest resource in the main assembly shouldn’t contain the culture name in it like ErrorStrings.en.resources. Instead, the manifest resource name should be ErrorStrings.resources. This can be verified manually by using ildasm.exe tool to check the names of the resources in the assembly manifest.

*      Do set the culture in the satellite assembly.

*      Do apply NeutralResourcesLanguageAttribute to the main assembly.

To use the NeutralResourcesLanguageAttribute in the main assembly where the neutral resources language is “en” and the neutral resources are located in a satellite assembly use the following code.

[Assembly:NeutralResourcesLangaugeAttribute(“en”, UltimateResourceFallbackLocation.ResourceLocation = Satellite)]

To use the NeutralResourcesLanguageAttribute in the main assembly where the neutral resources language is “en” and the neutral resources are located in the main assembly use the following code.

[Assembly:NeutralResourcesLangaugeAttribute(“en”, UltimateResourceFallbackLocation.ResourceLocation = MainAssembly)]

            Do not add code to the satellite assemblies as they are meant only for resources.

Satellite assemblies are culture specific. Each executable can have many satellite assemblies containing the resources localized for many cultures. If you add code to the satellite assemblies, you will have many copies of the code, which increases the maintenance cost.


Resource Naming

Because resources can be referenced via certain objects as if they were properties, the naming guidelines for resources are similar to property guidelines.

*      Do use PascalCasing for resource identifiers.

            Do provide descriptive rather than short identifiers. Keep them concise where possible, but do not sacrifice readability for space.

*      Do not use language-specific keywords of the main CLR languages.

*      Do not use syntactic characters which may have special meaning such as arithmetic operators (+, -, /, *, or %), or grouping characters ({, }, (, ), [, or ]).

*      Do not begin a resource identifier names with a numeric character.

*      Do use the dot separator to nest identifiers with a clear hierarchy. For example, if you design menu system resources, consider naming them like the following:

2        Menus.FileMenu.Close.Text

3        Menus.FileMenu.Close.Color

4        Menus.FileMenu.SaveAs.Text

5        Menus.HelpMenu.About.Text

*      Do use the following naming convention for exception message resources. The resource identifier should be the exception type name plus a short identifier of the exception separated by a dot:

6        ArgumentException.IllegalCharacters

7        ArgumentException.InvalidName

8        ArgumentException.FileNameIsMalformed

Comments (14)

  1. David M. Kean says:

    ‘UltimateResourceFallbackLocation’ doesn’t exist in the .NET Framework 1.0 or 1.1. Does it exist in 2.0?

  2. Ahmed AbouTaleb says:


    The UltimateResourceFallbackLocation is a new enumeration in Whidbey -V2.0- and it allows the user to store the neutral resources in a satellite assembly instead of storing them in the main assembly.

  3. John Schroedl says:

    Can anyone comment on whether there is a performance (I/O seek/load) advantage to putting Neutral resources in Satellite or Main Assemblies when you are running with the culture which would be loaded (e.g. English in the examples listed)?

    It seems to me that if en is your Neutral culture, it would be better to have it in a Satellite since one will be searched for regardless and that would eliminate an extra load attempt.

  4. Ahmed AbouTaleb says:

    Actually if en is your neutral resources culture and at the same time the current UI culture we check for that so it is better be in the main assembly and this way no probing is required.

  5. Misha Mikhailov says:

    It is difficult to detect misspelled resource identifier.

    string errorMsg = resourceManager.GetString(“FileNootFound”);

    Declare all resource identifiers as enums. Compiler will check for you.

    internal enum Errors





    string errorMsg = resourceManager.GetString(Errors.FileNotFound.ToString());

  6. Ahmed AbouTaleb says:

    Hi Misha,

    This is a very good point and we fixed it in Whidbey. In Whidbey for every resource file we create a class that has a strongly typed property for each resource element.



  7. Notre Poubelle says:

    It’s very interesting that the new recommendation is (generally) to put all resources, including any neutral resources in the satellite assemblies. I understand that the UltimateResourceFallbackLocation specifies which satellite will take over the role of the main assembly as the final resource fall back if everything else fails.

    Does putting all resources in satellite assemblies still allow for ClickOnce deployment? Is it still the same story as what’s given in point #6 of ?

  8. Ahmed AbouTaleb says:

    Hi Notre,

    Using satellites for all the resources including the neutral resources will work fine with ClickOnce if you used the UltimateResourceFallbackLocation.