Я работаю над довольно большим приложением ASP .NET Web Forms, которое в настоящее время используется в основном в Соединенных Штатах. Мы находимся в процессе развертывания его в других частях мира, что, конечно же, означает, что в настоящее время мы работаем над локализацией всех областей приложения. Вообще говоря, наш подход заключался в установке свойств CurrentCulture и CurrentUICulture текущего потока в начале каждого запроса для поддержки правильного форматирования и извлечения ресурсов в зависимости от локали текущего пользователя.
Однако в некоторых случаях нам необходимо запустить определенный фрагмент кода, используя культуру, отличную от культуры текущего пользователя. Например, «Пользователь А» живет в Германии, но работает в компании, которая ведет бизнес с другими компаниями во Франции. Когда «Пользователь A» хочет создать счет-фактуру (PDF) для одной из этих французских компаний, мы хотим, чтобы этот код создания счета-фактуры выполнялся с культурой «fr-FR», а не с культурой «de-DE».
I ' Я рассмотрел несколько способов сделать это легко, и мне интересно, правильно ли я это делаю. Меня больше всего беспокоит производительность и безопасность потоков.
Один из подходов включает статический метод, разработанный для выполнения данной задачи с предоставленной культурой. Примерно так:
public static void RunWithCulture(CultureInfo culture, Action task)
{
if (culture == null)
throw new ArgumentNullException("culture");
var originalCulture = new
{
Culture = Thread.CurrentThread.CurrentCulture,
UICulture = Thread.CurrentThread.CurrentUICulture
};
try
{
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
task();
}
finally
{
Thread.CurrentThread.CurrentCulture = originalCulture.Culture;
Thread.CurrentThread.CurrentUICulture = originalCulture.UICulture;
}
}
Этот метод затем можно было бы вызвать следующим образом:
var customerCulture = new CultureInfo(currentCustomer.Locale);
CultureRunner.RunWithCulture(customerCulture, () => invoiceService.CreateInvoice(currentCustomer.CustomerId));
Я также подумал о создании класса, реализующего IDisposable, который отвечал бы за установку культуры потока в его ctor и затем возвращал исходные культуры обратно в метод Dispose, так что вы можете назвать его так:
var customerCulture = new CultureInfo(currentCustomer.Locale);
using(new CultureRunner(currentCustomer.Locale))
{
invoiceService.CreateInvoice(currentCustomer.CustomerId);
}
Я все неправильно делаю? Какой из этих подходов предпочтительнее?