NotableDatePluginLoader Class
Definition
- Namespace
- Bodu.Globalization.Calendar.Plugins
- Assembly
- Bodu.Globalization.Calendar.Plugins.dll
- Package
- Bodu.Globalization.Calendar.Plugins 1.0.0
Loads notable-date plugins from assemblies, gating activation behind an IPluginTrustPolicy and registering the contributed algorithms with a NotableDateAlgorithmRegistry.
public static class NotableDatePluginLoader
- Inheritance
-
NotableDatePluginLoader
- Inherited Members
Examples
// Gate activation behind a strong-name trust policy, then register the plugin's algorithms.
IPluginTrustPolicy trust = new StrongNamePluginTrustPolicy(new[] { "c0ffee1234567890" });
INotableDatePlugin plugin = NotableDatePluginLoader.LoadFrom("Contoso.Calendar.Plugin.dll", trust);
NotableDateAlgorithmRegistry registry = new();
int registered = NotableDatePluginLoader.RegisterAlgorithms(plugin, registry);
// Wire the registry into the load and resolve pipeline so rules can reference the plugin keys.
NotableDateResource resource = NotableDateResourceLoader.Load(documentXml, _ => null, registry);
NotableDateService service = new(resource, new NotableDateServiceOptions { Algorithms = registry });
Remarks
Trust is evaluated before the plugin's entry-point type is activated, so an untrusted assembly's constructor never runs. The file-path overload loads the assembly into a dedicated AssemblyLoadContext.
When to use. Load a plugin with one of the LoadFrom overloads, register its contributed
algorithms into a NotableDateAlgorithmRegistry with one of the RegisterAlgorithms overloads,
then pass that registry to both NotableDateResourceLoader (so documents may reference the plugin's
algorithm keys during validation) and the NotableDateService (so they resolve at query time). Always
supply a production-grade IPluginTrustPolicy - AllowAllPluginTrustPolicy is for
development only.
Logging. Each LoadFrom / RegisterAlgorithms overload accepts an optional
ILogger (defaulting to Instance, so logging is opt-in). When supplied it
records a trust-policy rejection (Warning), a passed trust check (Debug),
an activated plugin (Information), and the number of algorithms a plugin contributed (Information).
These levels are fixed.
Methods
LoadFrom(Assembly, IPluginTrustPolicy, ILogger?)
Loads the plugin declared by an already-loaded assembly after a trust check.
[RequiresUnreferencedCode("Plugin loading inspects assemblies via reflection; plugin types and their algorithm implementations cannot be statically discovered by the trimmer.")]
[RequiresDynamicCode("Plugin loading executes assemblies discovered at run time, which native AOT cannot compile ahead of time. The AOT-compatible alternative is shipping rules as data (see the calendar rule-pack roadmap).")]
public static INotableDatePlugin LoadFrom(Assembly assembly, IPluginTrustPolicy trustPolicy, ILogger? logger = null)
Parameters
assemblyAssemblyThe assembly declaring the plugin via NotableDatePluginAttribute.
trustPolicyIPluginTrustPolicyThe policy that must trust the assembly before its plugin is activated.
loggerILoggerThe logger that receives diagnostics for the load. null selects Instance.
Returns
- INotableDatePlugin
The activated plugin.
Remarks
This overload offers a weaker guarantee than the path-based LoadFrom(string, IPluginTrustPolicy, ILogger?) and must not be used for untrusted input. The assembly is already loaded when the trust policy runs, so any module initializer or type-load side effect it carries has had the opportunity to execute before the trust check - a rejection here cannot prevent code that ran at load time.
The FileHash supplied to the policy is computed by re-reading Location from disk, not from the bytes that were actually loaded, so it does not close the time-of-check/time-of-use gap that the path-based overload avoids by hashing the in-memory image it maps. For untrusted assemblies, load through the path-based overload instead.
Exceptions
- ArgumentNullException
assemblyortrustPolicyis null.- PluginNotTrustedException
The trust policy rejected the assembly.
- PluginMissingAttributeException
The assembly does not declare a plugin attribute.
- PluginActivationException
The plugin type could not be activated or is not a plugin.
LoadFrom(string, IPluginTrustPolicy, ILogger?)
Loads the plugin declared by an assembly at a file path, into a dedicated load context, after a trust check.
[RequiresUnreferencedCode("Plugin loading inspects assemblies via reflection; plugin types and their algorithm implementations cannot be statically discovered by the trimmer.")]
[RequiresDynamicCode("Plugin loading executes assemblies discovered at run time, which native AOT cannot compile ahead of time. The AOT-compatible alternative is shipping rules as data (see the calendar rule-pack roadmap).")]
public static INotableDatePlugin LoadFrom(string assemblyPath, IPluginTrustPolicy trustPolicy, ILogger? logger = null)
Parameters
assemblyPathstringThe file path of the plugin assembly.
trustPolicyIPluginTrustPolicyThe policy that must trust the assembly before its plugin is activated.
loggerILoggerThe logger that receives diagnostics for the load. null selects Instance.
Returns
- INotableDatePlugin
The activated plugin.
Exceptions
- ArgumentNullException
assemblyPathortrustPolicyis null.- ArgumentException
assemblyPathis empty.- FileNotFoundException
No file exists at
assemblyPath.- DirectoryNotFoundException
A directory component of
assemblyPathdoes not exist.- UnauthorizedAccessException
The file cannot be read.
- NotableDatePluginException
The file is not a valid managed assembly image.
- PluginNotTrustedException
The trust policy rejected the assembly.
- PluginMissingAttributeException
The assembly does not declare a plugin attribute.
- PluginActivationException
The plugin type could not be loaded or activated, or is not a plugin.
LoadFromFile(string, IPluginTrustPolicy, ILogger?)
Loads the plugin declared by an assembly at a file path, into a dedicated load context, after a trust check, returning a handle that owns the context so the plugin can later be unloaded.
[RequiresUnreferencedCode("Plugin loading inspects assemblies via reflection; plugin types and their algorithm implementations cannot be statically discovered by the trimmer.")]
[RequiresDynamicCode("Plugin loading executes assemblies discovered at run time, which native AOT cannot compile ahead of time. The AOT-compatible alternative is shipping rules as data (see the calendar rule-pack roadmap).")]
public static NotableDatePluginHandle LoadFromFile(string assemblyPath, IPluginTrustPolicy trustPolicy, ILogger? logger = null)
Parameters
assemblyPathstringThe file path of the plugin assembly.
trustPolicyIPluginTrustPolicyThe policy that must trust the assembly before its plugin is activated.
loggerILoggerThe logger that receives diagnostics for the load. null selects Instance.
Returns
- NotableDatePluginHandle
A disposable handle owning the activated plugin and its load context.
Remarks
This overload behaves like LoadFrom(string, IPluginTrustPolicy, ILogger?) but additionally hands ownership of the plugin's collectible AssemblyLoadContext to the caller: disposing the returned handle initiates the unload. Unloading completes only once nothing references the plugin's types - a registry still holding the plugin's algorithms (or a service over that registry) keeps the context alive.
Exceptions
- ArgumentNullException
assemblyPathortrustPolicyis null.- ArgumentException
assemblyPathis empty.- FileNotFoundException
No file exists at
assemblyPath.- DirectoryNotFoundException
A directory component of
assemblyPathdoes not exist.- UnauthorizedAccessException
The file cannot be read.
- NotableDatePluginException
The file is not a valid managed assembly image.
- PluginNotTrustedException
The trust policy rejected the assembly.
- PluginMissingAttributeException
The assembly does not declare a plugin attribute.
- PluginActivationException
The plugin type could not be loaded or activated, or is not a plugin.
RegisterAlgorithms(INotableDatePlugin, NotableDateAlgorithmRegistry, PluginAlgorithmRegistrationOptions, ILogger?)
Registers the algorithms contributed by a plugin with a registry under the supplied collision policy.
public static int RegisterAlgorithms(INotableDatePlugin plugin, NotableDateAlgorithmRegistry registry, PluginAlgorithmRegistrationOptions options, ILogger? logger = null)
Parameters
pluginINotableDatePluginThe plugin whose algorithms are registered.
registryNotableDateAlgorithmRegistryThe registry to populate.
optionsPluginAlgorithmRegistrationOptionsThe options controlling how colliding keys are treated.
loggerILoggerThe logger that receives diagnostics for the registration. null selects Instance.
Returns
- int
The number of algorithms registered.
Remarks
Registration is atomic: the plugin's contribution is fully staged and validated before the registry is touched, so a faulting or malformed plugin never leaves the registry partially mutated. With AllowOverride enabled, each replacement of a built-in or existing key is logged at Warning.
Exceptions
- ArgumentNullException
plugin,registry, oroptionsis null.- NotableDatePluginException
The plugin's contribution is malformed or faults, or a contributed key collides with a built-in algorithm or an existing registration while AllowOverride is false. The registry is left unchanged.
RegisterAlgorithms(INotableDatePlugin, NotableDateAlgorithmRegistry, ILogger?)
Registers the algorithms contributed by a plugin with a registry, rejecting keys that collide with built-in algorithms or existing registrations.
public static int RegisterAlgorithms(INotableDatePlugin plugin, NotableDateAlgorithmRegistry registry, ILogger? logger = null)
Parameters
pluginINotableDatePluginThe plugin whose algorithms are registered.
registryNotableDateAlgorithmRegistryThe registry to populate.
loggerILoggerThe logger that receives diagnostics for the registration. null selects Instance.
Returns
- int
The number of algorithms registered.
Exceptions
- ArgumentNullException
pluginorregistryis null.- NotableDatePluginException
The plugin's contribution is malformed or faults, or a contributed key collides with a built-in algorithm or an existing registration. The registry is left unchanged.
Applies to
| Product | Versions |
|---|---|
| .NET | 8, 10 |