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, theactive
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:
- Exactly match case.
- Be in lower case.
If
active
is the AssemblyLoadContext.Default instance, by running the default satellite (resource) assembly probing logic.Calling the AssemblyLoadContext.Load function.
Raising the AssemblyLoadContext.Resolving event.
Raising the AppDomain.AssemblyResolve event.
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.
Finally,
- If the runtime doesn't find a resource file for a default (fallback) culture, a MissingManifestResourceException or MissingSatelliteAssemblyException exception is thrown.
- If the resource file is found but the requested resource isn't present, the request returns
null
.