Estoy construyendo una aplicación que es multilingüe, multi-timezoned y n-tier. Todas las fechas se almacenan en la base de datos en UTC y todos los objetos del modelo se rellenan con horas UTC. Sin embargo, los tiempos UTC nunca se muestran (a menos que el usuario tenga su zona horaria configurada en UTC).¿Dónde debe realizarse la conversión de valores de presentación en arquitectura de varios niveles?
Esto significa que necesito convertir las propiedades de tiempo en la zona horaria del usuario correcta repetitivamente. La repetición es siempre el signo de un código incorrecto o una mejor manera, así que estaba tratando de encontrar la mejor estrategia para implementar. Aunque esta es una lógica de presentación efectiva, mis pensamientos han sido variados porque parece que el modelo debería conocer los valores correctos para el usuario actual. Hasta ahora mis pensamientos son:
Utilice una clase de ayudante estático y luego llámelo cada vez que se use la propiedad del modelo. Esto parece propenso al error o al olvido, y hace que los cálculos sean engorrosos.
Envuelva el objeto modelo en un objeto viewmodel. Esto es igualmente engorroso especialmente cuando se trata de listas de objetos.
Escriba un método de extensión para el modelo que existe solo en la capa de presentación. Esto parece más limpio pero no intuitivo.
Cree una interfaz en la capa modelo para la conversión. Implementa el ayudante en la capa de presentación y dale a la capa del modelo la implementación. El modelo tiene propiedades que usan la interfaz para convertir la hora. Parece que debería estar rompiendo la separación de las preocupaciones, pero parece que no. Si tuviera un convertidor predeterminado, entonces no tendría que preocuparse por obtener excepciones de objetos nulos, sin embargo, la capa del modelo (actualmente POCO) necesitaría un contenedor para el asistente de conversión que parece desordenado.
Cree una conversión al método de zona horaria local en el modelo y pase en la zona horaria actual.
Me interesan las opiniones sobre estas estrategias o cualquier otra que debería o podría estar utilizando en lugar de estas.
actualización Lo que he hecho actualmente es crear un ITimeConvertor y un ITimeConvertorFactory dentro de la capa del modelo. Luego creé implementaciones predeterminadas de estos que simplemente devuelven el valor de fecha original. Dentro de la capa del modelo, he agregado propiedades de tiempo local para cada propiedad UTC existente que estaba originalmente en el modelo. Dentro de estas propiedades utilizo la fábrica para obtener un convertidor y convertir el valor UTC en cada sentido en getter y setter. He tenido que agregar una clase de configuración estática en la capa de modelo (que realmente no me gusta) como un lugar para almacenar la fábrica actual de timeconvertors. En la parte de la aplicación web, implemento ITimeConvertorFactory y ITimeConvertor como WebTimeConvertorFactory y WebTimeConvertor. El WebTimeConvertor conoce la sesión y el usuario actual, de modo que puede captar la zona horaria actual. WebTimeConvertorFactory crea WebTimeConvertors. Cuando se inicia la aplicación (application_onstart en global.asax) creo la fábrica y la paso a la propiedad de configuración estática de la capa de modelo. Esto permite que mi capa de modelo pueda convertir las horas locales, mientras que la capa de datos solo conoce las propiedades de fecha UTC. También significa que puedo pasar localtimes directamente en el modelo y convertirlo con precisión siempre que la aplicación de consumo haya proporcionado una fábrica de convertidores. Como las propiedades UTC no se modifican, aún se pueden usar en cualquier lugar dentro de la aplicación. Aunque parecía una gran cantidad de código, encontré esta solución bastante limpia una vez implementada, ya que permite a otros consumidores del servicio implementar su conversión de tiempo de cualquier forma que quieran (si es que lo hace) manteniendo el consumo de las propiedades del modelo razonablemente obvio.
Todavía estoy abierto a mejores soluciones y críticas de mi solución actual.
Supongo que ese es mi punto de vista, ¿debería saber mi capa de modelo en qué zona horaria está el usuario? Actualmente no. Mi debate interno es si esta es una presentación o una decisión de la capa modelo. Un usuario POCO almacena la zona horaria pero el usuario POCO no tiene atributos de tiempo que otros POCO hacen. Entonces estoy atando la visualización de los valores de un POCO a otro que no era necesario antes ... – toxaq
He actualizado mi respuesta. – henginy
Excelente, gracias. Veo lo que estás diciendo y para mí realmente es una sacudida entre dos "males necesarios". Como me gusta la simplicidad del consumo (y dado que actualmente soy el único que trabaja en ello), me mantendré en mi camino por el momento, pero creo que el suyo es igualmente válido y, desde luego, más transparente/legible. – toxaq