No importa, siempre y cuando sea una clase estática. Se trata de convenciones .
Nuestra convención es que cada "capa" (web, servicios, datos) tiene un solo archivo llamado AutoMapperXConfiguration.cs
, con un único método llamado Configure()
, donde X
está la capa.
El Configure()
método luego llama a private
métodos para cada área.
Aquí hay un ejemplo de nuestra configuración de nivel web:
public static class AutoMapperWebConfiguration
{
public static void Configure()
{
ConfigureUserMapping();
ConfigurePostMapping();
}
private static void ConfigureUserMapping()
{
Mapper.CreateMap<User,UserViewModel>();
}
// ... etc
}
Creamos un método para cada "agregado" (Usuario, Publicar), para que las cosas estén bien separadas.
Entonces tu Global.asax
:
AutoMapperWebConfiguration.Configure();
AutoMapperServicesConfiguration.Configure();
AutoMapperDomainConfiguration.Configure();
// etc
Es algo así como una "interfaz de palabras": no puede imponerla, pero lo espera, por lo que puede codificar (y refactorizar) si es necesario.
EDITAR:
Solo pensé en mencionar que ahora uso los perfiles de AutoMapper , por lo que el ejemplo anterior se convierte en:
public static class AutoMapperWebConfiguration
{
public static void Configure()
{
Mapper.Initialize(cfg =>
{
cfg.AddProfile(new UserProfile());
cfg.AddProfile(new PostProfile());
});
}
}
public class UserProfile : Profile
{
protected override void Configure()
{
Mapper.CreateMap<User,UserViewModel>();
}
}
Mucho más limpio / más robusto.
Mapper.Initialize
en cada clase de configuración sobrescribe los perfiles anteriores agregados? Si es así, ¿qué se debe usar en lugar de Inicializar?Mapper.CreateMap()
ahora está obsoleto.'Mapper.Map<TSource, TDestination>(TSource, TDestination)' is obsolete: 'The static API will be removed in version 5.0. Use a MapperConfiguration instance and store statically as needed. Use CreateMapper to create a mapper instance.'
. ¿Cómo actualizaría su ejemplo para cumplir con los nuevos requisitos?Realmente puede ponerlo en cualquier lugar siempre que su proyecto web haga referencia al ensamblaje en el que se encuentra. En su situación, lo pondría en la capa de servicio, ya que será accesible para la capa web y la capa de servicio y más tarde si decide hacer una aplicación de consola o está haciendo un proyecto de prueba unitaria, la configuración de mapeo también estará disponible en esos proyectos.
En su Global.asax, llamará al método que establece todos sus mapas. Vea abajo:
Archivo AutoMapperBootStrapper.cs
Global.asax al inicio de la aplicación
solo llama
Ahora, algunas personas argumentarán en contra de que este método viole algunos principios SÓLIDOS, que tienen argumentos válidos. Aquí están para la lectura.
¿La configuración de Automapper en Bootstrapper viola el principio abierto-cerrado?
fuente
Actualización: el enfoque publicado aquí ya no es válido, ya que
SelfProfiler
se ha eliminado a partir de AutoMapper v2.Adoptaría un enfoque similar al de Thoai. Pero usaría la
SelfProfiler<>
clase incorporada para manejar los mapas, luego usaría laMapper.SelfConfigure
función para inicializar.Usando este objeto como fuente:
Y estos como destino:
Puede crear estos perfiles:
Para inicializar en su aplicación, cree esta clase
Agregue esta línea a su archivo global.asax.cs:
AutoMapperConfiguration.Initialize()
Ahora puede colocar sus clases de mapeo donde tengan sentido para usted y no preocuparse por una clase de mapeo monolítico.
fuente
Para aquellos de ustedes que se adhieren a lo siguiente:
Hice un combo entre perfiles y aproveché mi contenedor ioc:
Configuración de IoC:
Ejemplo de configuración:
Ejemplo de uso:
La desventaja es que debe hacer referencia al Mapper mediante la interfaz IMappingEngine en lugar del Mapper estático, pero esa es una convención con la que puedo vivir.
fuente
Todas las soluciones anteriores proporcionan un método estático para llamar (desde app_start o desde cualquier lugar) al que debería llamar a otros métodos para configurar partes de la configuración de mapeo. Pero, si tiene una aplicación modular, esos módulos pueden conectarse y desconectarse de la aplicación en cualquier momento, estas soluciones no funcionan. Sugiero usar una
WebActivator
biblioteca que pueda registrar algunos métodos para ejecutarapp_pre_start
y enapp_post_start
cualquier lugar:Puede instalar a
WebActivator
través de NuGet.fuente
MyModule1
proyecto (o como se llame el nombre de su proyecto) simplemente cree una clase llamadaInitMapInModule1
y coloque el código dentro del archivo; para otros módulos, haga lo mismo.Además de la mejor respuesta, una buena manera es usar Autofac IoC liberary para agregar algo de automatización. Con esto simplemente define sus perfiles independientemente de las iniciaciones.
y llamando a esta línea en
Application_Start
método:El código anterior encuentra todas las subclases de perfil y las inicia automáticamente.
fuente
Poner toda la lógica de mapeo en 1 ubicación no es una buena práctica para mí. Porque la clase de mapeo será extremadamente grande y muy difícil de mantener.
Recomiendo poner el material de mapeo junto con la clase ViewModel en el mismo archivo cs. Puede navegar fácilmente a la definición de mapeo que desea siguiendo esta convención. Además, al crear la clase de mapeo, puede hacer referencia a las propiedades de ViewModel más rápido ya que están en el mismo archivo.
Entonces su clase de modelo de vista se verá así:
fuente
Desde la nueva versión de AutoMapper que utiliza el método estático Mapper.Map () está en desuso. Por lo tanto, puede agregar MapperConfiguration como propiedad estática a MvcApplication (Global.asax.cs) y usarlo para crear una instancia de Mapper.
App_Start
Global.asax.cs
BaseController.cs
https://github.com/AutoMapper/AutoMapper/wiki/Migrating-from-static-API
fuente
Para aquellos que están (perdidos) usando:
Así es como logré integrar AutoMapper en la " nueva forma ". Además, un enorme gracias a esta respuesta (y pregunta)
1 - Creé una carpeta en el proyecto WebAPI llamada "ProfileMappers". En esta carpeta coloco todas mis clases de perfiles que crean mis asignaciones:
2 - En mi App_Start, tengo un SimpleInjectorApiInitializer que configura mi contenedor SimpleInjector:
3 - Startup.cs
4 - Luego, en su controlador, simplemente inyecte como generalmente una interfaz IMapper:
fuente
Para programadores de vb.net que usan la nueva versión (5.x) de AutoMapper.
Global.asax.vb:
AutoMapperConfiguration:
Perfiles:
Cartografía:
fuente
Protected Overrides Sub Configure()
está en desuso. Todo sigue igual pero esta línea debería ser:Public Sub New()