I'm starting to use AutoMapper (latest version from Nuget) into my project (WebApi2, framework 4.5.1) and using SimpleInjector (latest version from Nuget).
My problem is that I don't know how to configure SimpleInjector to inject IMappingEngine into my models by constructor.
Right now I'm getting the error: Unmapped properties: MappingEngine
I'm using the IMappingEngine interface.
I have a AutoMapperProfile class with all the Mapper.CreateMap<>
Example of AutoMapperConfig
public class WebApiAutomapperProfile : Profile { /// <summary> /// The configure. /// </summary> protected override void Configure() { this.CreateMap<Entity, EntityModel>(); } } The reason the models are receiving an IMappingEngine is that some mappings attributes have other mapping inside.
In Global.asax (method Application_Start()) I'm calling:
GlobalConfiguration.Configure(WebApiConfig.Register); webApiContainer = new Container(); webApiContainer.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle(); IocConfig.RegisterIoc(GlobalConfiguration.Configuration, webApiContainer); IocConfig.cs
public static class IocConfig { public static void RegisterIoc(HttpConfiguration config, Container container) { InstallDependencies(container); RegisterDependencyResolver(container); } private static void InstallDependencies(Container container) { new ServiceInstallerSimpleInjector().Install(container); } private static void RegisterDependencyResolver(Container container) { GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container); } ServiceInstallerSimpleInjector
public class ServiceInstallerSimpleInjector : IServiceInstallerSimpleInjector { // Automapper registrations container.Register(typeof(ITypeMapFactory), typeof(TypeMapFactory), Lifestyle.Scoped); container.RegisterCollection<IObjectMapper>(MapperRegistry.Mappers); var configurationRegistration = Lifestyle.Scoped.CreateRegistration<ConfigurationStore>(container); container.AddRegistration(typeof(IConfiguration), configurationRegistration); container.AddRegistration(typeof(IConfigurationProvider), configurationRegistration); // The initialization runs all the map creation once so it is then done when you come to do your mapping. // You can create a map whenever you want, but this will slow your code down as the mapping creation involves reflection. Mapper.Initialize(config => { config.ConstructServicesUsing(container.GetInstance); config.AddProfile(new WebApiAutomapperProfile()); config.AddGlobalIgnore("Errors"); config.AddGlobalIgnore("IsModelValid"); config.AddGlobalIgnore("BaseValidator"); config.AddGlobalIgnore("AuditInformation"); }); container.RegisterSingleton<IMappingEngine>(Mapper.Engine); Mapper.AssertConfigurationIsValid(); container.RegisterWebApiControllers(GlobalConfiguration.Configuration); container.Verify(); } Then each Controller receives a IMappingEngine in the constructor and uses:
MappingEngine.Map<> Models class sample
public class EntityModel : BaseModel.BaseModel<EntityModel > { public EntityModel(IMappingEngine mappingEngine) : base(mappingEngine) { } } BaseModel
public abstract class BaseModel<T> : IBaseModel where T : class { public IMappingEngine MappingEngine { get; set; } protected BaseModel(IMappingEngine mappingEngine) { this.MappingEngine = mappingEngine; } } The error message says:
Type needs to have a constructor with 0 args or only optional args\r\nParameter name: type Mapping types: Entity -> EntityModel Model.Entity -> WebApi.Models.EntityModel Destination path: EntityModel Source value: System.Data.Entity.DynamicProxies.Entity_1D417730D5BE3DEAF6292D57AB49B32FA18136A1DCF74193E8716EC6EE4DC62B The problem is that IMappingEngine mappingEngine is not being injected into the Model's constructor. The problem is how to make it work.
The error is thrown when I'm trying to do a .Map
return this.MappingEngine.Map<Entity,EntityModel>(this.EntityRepository.AllMaterialized().FirstOrDefault()); And this is the Stacktrace
at WebApi.Controllers.Api.EntityController.Get() in c:\Users\Guillermo\Downloads\Backend\WebApi\Controllers\Api\EntityController.cs:line 108 at lambda_method(Closure , Object , Object[] ) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken) Anything missing or wrong?
Thanks in advance! Guillermo.