ValidationLocalizationOptions.LocalizerProvider Property

Definition

Gets or sets the delegate that controls which IStringLocalizer is used for a given declaring type. The declaring type is the type that contains the property being validated, or null when the validation pipeline has no declaring type to attribute the message to (e.g., top-level Minimal API parameters).

public:
 property Func<Type ^, Microsoft::Extensions::Localization::IStringLocalizerFactory ^, Microsoft::Extensions::Localization::IStringLocalizer ^> ^ LocalizerProvider { Func<Type ^, Microsoft::Extensions::Localization::IStringLocalizerFactory ^, Microsoft::Extensions::Localization::IStringLocalizer ^> ^ get(); void set(Func<Type ^, Microsoft::Extensions::Localization::IStringLocalizerFactory ^, Microsoft::Extensions::Localization::IStringLocalizer ^> ^ value); };
public Func<Type?,Microsoft.Extensions.Localization.IStringLocalizerFactory,Microsoft.Extensions.Localization.IStringLocalizer>? LocalizerProvider { get; set; }
member this.LocalizerProvider : Func<Type, Microsoft.Extensions.Localization.IStringLocalizerFactory, Microsoft.Extensions.Localization.IStringLocalizer> with get, set
Public Property LocalizerProvider As Func(Of Type, IStringLocalizerFactory, IStringLocalizer)

Property Value

Remarks

When null (the default), Create(Type) is called with the declaring type, which follows the standard resource file naming convention (e.g., Resources/Models.Customer.fr.resx for type Models.Customer). For declaring-type-less invocations, the no-provider fallback uses typeof(object). In that case the resolved resource source is rarely useful, which is why configuring this delegate (or using AddValidationLocalization<TResource>()) is recommended for Minimal API parameter validation.

options.LocalizerProvider = (type, factory) =>
    factory.Create(typeof(SharedValidationMessages));

For the shared-resource pattern above, prefer the dedicated AddValidationLocalization<TResource>() overload, which configures LocalizerProvider for you (with a single-instance optimization that skips re-resolving the same IStringLocalizer on every validation call).

The delegate must return a non-null IStringLocalizer. Returning null causes an InvalidOperationException to be thrown the next time validation tries to localize a message for that declaring type.

Caching: the validation pipeline does not cache the IStringLocalizer returned by this delegate. The delegate is invoked once per call to ResolveDisplayName(DisplayNameLocalizationContext) and ResolveErrorMessage(ErrorMessageLocalizationContext), so the underlying IStringLocalizerFactory is responsible for caching localizer instances if instance creation is expensive. However, the default factory registered by AddLocalization() (ResourceManagerStringLocalizerFactory) caches its results internally. If your delegate itself does meaningful work beyond calling the factory, capture the result in a closure to amortize that cost across calls.

Applies to