net - set current culture c#
¿Es este un buen enfoque para cambiar temporalmente la cultura del hilo actual? (3)
Me gusta el enfoque de using
. También crearía un método de extensión para que las cosas se lean mejor:
var customerCulture = new CultureInfo(currentCustomer.Locale);
using (customerCulture.AsCurrent()) {
invoiceService.CreateInvoice(currentCustomer.CustomerId);
}
Algo como esto:
public static class CultureInfoExtensions {
public static IDisposable AsCurrent(this CultureInfo culture) {
return new CultureRunner(culture);
}
}
O, si siempre es su objeto de cliente el que establece la cultura, otro método de extensión elevaría aún más la abstracción:
using (currentCustomer.CultureContext()) {
invoiceService.CreateInvoice(currentCustomer.CustomerId);
}
Trabajo en una aplicación de formularios web .NET bastante grande que actualmente se usa principalmente en los Estados Unidos. Estamos en proceso de extenderlo a otras partes del mundo, lo que, por supuesto, significa que actualmente estamos trabajando en la localización de todas las áreas de la aplicación. En términos generales, nuestro enfoque ha sido establecer las propiedades CurrentCulture y CurrentUICulture del subproceso actual al comienzo de cada solicitud para admitir el formato y la extracción de recursos adecuados en función de la configuración regional del usuario actual.
En algunos casos, sin embargo, tenemos la necesidad de ejecutar una cierta cantidad de código utilizando una cultura diferente a la cultura del usuario actual. Por ejemplo, el ''Usuario A'' vive en Alemania pero trabaja para una compañía que hace negocios con otras compañías en Francia. Cuando el "Usuario A" quiere crear una factura (PDF) para una de esas compañías francesas, queremos que ese código de generación de factura se ejecute con la cultura "fr-FR" en lugar de la cultura "de-DE".
He considerado un par de maneras de hacer esto fácilmente y me pregunto si estoy haciendo esto correctamente. Mis principales preocupaciones están relacionadas con el rendimiento y la seguridad de los hilos.
Un enfoque implica un método estático diseñado para ejecutar una tarea determinada con una cultura proporcionada. Algo como esto:
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;
}
}
Este método podría entonces ser invocado así:
var customerCulture = new CultureInfo(currentCustomer.Locale);
CultureRunner.RunWithCulture(customerCulture, () => invoiceService.CreateInvoice(currentCustomer.CustomerId));
También he considerado crear una clase que implemente IDisposable que sea responsable de establecer la cultura del hilo en su ctor y luego devolver las culturas originales nuevamente en el método de Disposición, por lo que podría llamarlo así:
var customerCulture = new CultureInfo(currentCustomer.Locale);
using(new CultureRunner(currentCustomer.Locale))
{
invoiceService.CreateInvoice(currentCustomer.CustomerId);
}
¿Estoy yendo todo esto mal? ¿Cuál, si alguno de estos enfoques es preferible?
Vota por el delegado RunWithCulture enfoque aquí.
Siéntase libre de agregar razones / enlaces a esta publicación de wiki.
Ya que me estás preguntando si el cambio temporal de la Cultura del hilo actual es una buena idea, solo puedo responder: no . Podría usarse si y solo no hay otra manera de hacer que las cosas funcionen. Eso es solo porque tal cambio es propenso a errores. De acuerdo, no olvidará volver a cambiar las cosas con el código que le dio Jordão (respeto), pero ...
Por ahora tienes clientes que quieren crear facturas francesas. Supongo que desea utilizar los formatos de fecha, número y moneda en francés. Está bien. Pero ... ¿Qué pasaría si en el futuro se imprimiera cierto futuro con otro formato, por ejemplo, este alemán original? ¿Vas a crear algún tipo de trabajo feo?
Entiendo que podría estar fuera de su control (como Reporting Software podría ser una solución independiente de terceros y no podría controlar cómo está manejando ToString()
) pero si está bajo su control, recomendaría ingresar los datos en Formato correcto en primer lugar. Por ejemplo, podría crear algunos datos de capa de transformación (DTO) y formato de datos correctamente (a través de ToString(IFormatProvider)
). Sé que esto es un gran esfuerzo, pero como estás preguntando sobre la forma correcta de hacer las cosas ...
Si estuviéramos en la misma organización y yo hiciera la revisión del código, podría estar seguro de que señalaría el cambio temporal de la cultura como un defecto. Por lo general, hay una manera de evitar esto.