Я работаю над довольно большим приложением ASP .NET Web Forms, которое в настоящее время используется в основном в Соединенных Штатах.Мы находимся в процессе его развертывания в других частях мира, что, конечно, означает, что в настоящее время мы работаем над локализацией всех областей приложения.Вообще говоря, наш подход состоял в том, чтобы установить свойства CurrentCulture и CurrentUICulture текущего потока в начале каждого запроса для поддержки правильного форматирования и извлечения ресурсов на основе локали текущего пользователя.
В некоторых случаях, однако, мы имеемнеобходимость запуска определенного фрагмента кода с использованием культуры, отличной от культуры текущего пользователя.Например, «Пользователь А» живет в Германии, но работает на компанию, которая ведет бизнес с другими компаниями во Франции.Когда «Пользователь A» хочет создать счет-фактуру (PDF) для одной из этих французских компаний, мы хотим, чтобы этот код генерации счетов-фактур выполнялся с культурой «fr-FR», а не с культурой «de-DE».
Я рассмотрел несколько способов сделать это легко и мне интересно, правильно ли я это делаю.Мои основные проблемы связаны с производительностью и безопасностью потоков.
Один из подходов заключается в использовании статического метода, предназначенного для выполнения определенной задачи с предоставленной культурой.Примерно так:
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);
}
Я все об этом говорю неправильно?Какой, если какой-либо из этих подходов предпочтительнее?