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