Satellite assembly loading algorithm

本文内容

Satellite assemblies are used to store localized resources customized for language and culture.

Satellite assemblies use a different loading algorithm than general managed assemblies.

When are satellite assemblies loaded?

Satellite assemblies are loaded when loading a localized resource.

The basic API to load localized resources is the System.Resources.ResourceManager class. Ultimately the ResourceManager class will call the GetSatelliteAssembly method for each CultureInfo.Name.

Higher-level APIs may abstract the low-level API.

Algorithm

The .NET Core resource fallback process involves the following steps:

  • Determine the active AssemblyLoadContext instance. In all cases, the active instance is the executing assembly's AssemblyLoadContext.

  • The active instance attempts to load a satellite assembly for the requested culture in priority order by:

    • Checking its cache.

    • Checking the directory of the currently executing assembly for a subdirectory that matches the requested CultureInfo.Name (for example es-MX).

Note

This feature was not implemented in .NET Core before 3.0.

Note

On Linux and macOS, the subdirectory is case-sensitive and must either:

  1. - Exactly match case.
  2. - Be in lower case.
  • If a satellite assembly is loaded:

    • The AppDomain.AssemblyLoad event is raised.
    • The assembly is searched it for the requested resource. If the runtime finds the resource in the assembly, it uses it. If it doesn't find the resource, it continues the search.

Note

To find a resource within the satellite assembly, the runtime searches for the resource file requested by the ResourceManager for the current CultureInfo.Name. Within the resource file, it searches for the requested resource name. If either is not found, the resource is treated as not found.

  • The runtime next searches the parent culture assemblies through many potential levels, each time repeating steps 2 & 3.

Each culture has only one parent, which is defined by the CultureInfo.Parent property.

The search for parent cultures stops when a culture's Parent property is CultureInfo.InvariantCulture.

For the InvariantCulture, we don't return to steps 2 & 3, but rather continue with step 5.

  • If the resource is still not found, the resource for the default (fallback) culture is used.

Typically, the resources for the default culture are included in the main application assembly. However, you can specify UltimateResourceFallbackLocation.Satellite for the NeutralResourcesLanguageAttribute.Location property. This value indicates that the ultimate fallback location for resources is a satellite assembly rather than the main assembly.

Note

The default culture is the ultimate fallback. Therefore, we recommend that you always include an exhaustive set of resources in the default resource file. This helps prevent exceptions from being thrown. By having an exhaustive set, you provide a fallback for all resources and ensure that at least one resource is always present for the user, even if it is not culturally specific.