I'm working with Web.API/.Net 7 and need to validate and conform a list of language ranges
coming from Accept-Language
header. The langauge ranges should be checked against the list of possible CultureInfo.Name
options. Language ranges must not adhere to lower and upper case writings. So in case of a match the correctly formatted CultureInfo.Name
should be used.
In Is there a way to "try parse" a string to System.Globalization.CultureInfo the recommended option for validation is to use CultureInfo.GetCultures(CultureTypes.AllCultures)
.
One can use LINQ Find()
to find a matching element. Even CultureInfo.GetCultures(CultureTypes.AllCultures)
returns a sorted list of names already, it won't help much for Find()
.
I think that there is a more performant solution than to scan 800+ entries of CultureInfos
for each language in the Accept-Language
header on each request.
In the above post it was recommended to put all elements in a dictionary and search that.
static readonly Dictionary<string, CultureInfo> CultureDict =
CultureInfo.GetCultures(CultureTypes.AllCultures).ToDictionary(c => c.Name);
Would a SortedList
with BinarySearch
also be an option?
How can I load that Dictionary
or SortedList
into memory only one time and access it from all requests? Do I need a Singleton? Are there any issues with parallel read access?
I only have basic understanding of those specifics, but what are the options?
The dictionary you have is the best option:
You could declare the dictionary via an interface and inject the dependency so it is available in your validation classes.
For example:
public interface ISingleton {
Dictionary<string, CultureInfo> Instance { get; }
}
service.AddSingleton<ISingleton>(() => new Singleton {Instance = CultureInfo.GetCultures(CultureTypes.AllCultures).ToDictionary(c => c.Name)});
The one benefit with using dependency injection is your classes no longer depend on static properties and this makes things more reusable and testable.