net microsoft iservicecollection injection extensions dependencyinjection dependency asp c# dependency-injection asp.net-mvc-5 ninject automapper

c# - microsoft - automapper profile



Excepción de Automapper: "Falta la configuración del mapa de tipo o la asignación no admitida". (5)

Estoy tratando de usar Ninject en una aplicación ASP.NET MVC 5 que usa AutoMapper para mapear el Modelo al Modelo de Vista y viceversa. Lamentablemente recibo un mensaje de error que indica que falta la configuración del mapa de tipos.

Creé un resolutor de dependencias Ninject:

namespace MyNamespace.Infrastructure { public class NinjectDependencyResolver: IDependencyResolver { private IKernel kernel; public NinjectDependencyResolver(IKernel kernelParam) { kernel = kernelParam; AddBindings(); } public object GetService(Type serviceType) { return kernel.TryGet(serviceType); } public IEnumerable<object> GetServices(Type serviceType) { return kernel.GetAll(serviceType); } private void AddBindings() { kernel.Bind<IMyBLL>().To<MyBLL>(); } } }

Yo uso esto para crear un controlador:

namespace MyNamespace.Controllers { [Authorize] public class HomeController : Controller { private IMyBLL _myBLL; public HomeController(IMyBLL myBLLParam) { _myBLL = myBLLParam; } public PartialViewResult AddRecord() { return PartialView(new AddRecordViewModel()); } [HttpPost] public void AddRecord(AddRecordViewModel recordViewModel) { var record = Mapper.Map<Record>(recordViewModel); _myBLL.AddRecord(record, User.Identity.Name); } } }

Global.asax:

namespace MyNamespace.WebApplication { public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { ApplicationUserManager.StartupAsync(); AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); AutoMapperWebConfiguration.Configure(); } } }

Esto llama a la configuración de AutoMapper:

namespace MyNamespace.WebApplication.Infrastructure { public static class AutoMapperWebConfiguration { public static void Configure() { Mapper.Initialize(cfg => cfg.AddProfile(new RecordProfile())); } } public class RecordProfile : Profile { protected override void Configure() { Mapper.CreateMap<AddRecordViewModel, Record>().ReverseMap(); } } }

Cuando ejecuto esto recibo el siguiente mensaje de error:

Missing type map configuration or unsupported mapping. Mapping types: AddRecordViewModel -> Record MyNamespace.WebApplication.ViewModels.Home.AddRecordViewModel -> MyNamespace.Model.Record Destination path: Record Source value: MyNamespace.WebApplication.ViewModels.Home.AddRecordViewModel

¿Extraño algo? Funcionó bien antes de usar el resolvedor de dependencias Ninject. Ahora no parece encontrar las asignaciones.

Editar:

Si agrego la Creación de mapas directamente al método del controlador, funciona:

[HttpPost] public void AddRecord(AddRecordViewModel recordViewModel) { Mapper.CreateMap<AddRecordViewModel, Record>().ReverseMap(); var record = Mapper.Map<Record>(recordViewModel); _myBLL.AddRecord(record, User.Identity.Name); }

El mapeo en sí y los modelos y modelos de vista no parecen ser el problema. Supongo que el programa de alguna manera no encuentra las asignaciones.

Incluso si llamo a la Configuración web de Auto Mapper en el método del controlador, funciona:

public void AddRecord(AddRecordViewModel recordViewModel) { Infrastructure.AutoMapperWebConfiguration.Configure(); var record = Mapper.Map<Record>(recordViewModel); _myBLL.AddRecord(record, User.Identity.Name); }


Necesita agregar el mapeo inverso también. Puedes hacerlo de dos maneras:

Mapper.CreateMap<AddRecordViewModel, Record>(); Mapper.CreateMap<Record, AddRecordViewModel>();

o de una vez, así:

Mapper.CreateMap<AddRecordViewModel, Record>().ReverseMap();

Lo último es preferible si me preguntas.


No llame a Mapper.CreateMap en su perfil. Call base.CreateMap, y estás configurado:

public class RecordProfile : Profile { protected override void Configure() { base.CreateMap<AddRecordViewModel, Record>().ReverseMap(); } }


Tuve un problema similar, olvidé registrarme en Global.asax

public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { AutoMapperConfig.RegisterMappings(); } }


En mi caso, el problema fue que algunas asignaciones de Automapper predeterminadas se registraron con el IoC.

builder.Register(_ => AutomapperConfiguration.Configure()).As<IMapper>().SingleInstance();

La asignación que estaba fallando se registró en un lugar diferente, la configuración del servicio

static void Main(string[] args) { var container = ConfigureDependencies(); AutoMapping.Configure();

El proyecto en el que se obtenía este error era un proyecto de prueba en el que no se ejecutaba la configuración del servicio. Cuando se depuró tuvo la ilusión de que las asignaciones anómalas se registraron, como podría ver las asignaciones de IoC.

Solución, asegúrese de que todas las asignaciones se hayan registrado en la solución de prueba.


Mapper.Initialize() debe usarse estrictamente una vez por solución.

Si llamas a Initialize() algún momento más adelante, anulará todas tus asignaciones anteriores. Inspeccione su código con atención, supongo, encontrará una llamada de este método en otro lugar.

PD: Ese no fue el comportamiento inicial de Automapper antes, como pude ver en los códigos creados hace 3 o más años en GitHub.