AutoMapper 未使用 SimpleInjector 和 WebApi2 实例化 IMappingEngine
AutoMapper not instantiating IMappingEngine using SimpleInjector and WebApi2
我开始在我的项目(WebApi2,框架 4.5.1)中使用 AutoMapper(Nuget 的最新版本)并使用 SimpleInjector(Nuget 的最新版本)。
我的问题是我不知道如何配置 SimpleInjector 以通过构造函数将 IMappingEngine 注入我的模型。
现在我收到错误:
未映射的属性:MappingEngine
我正在使用 IMappingEngine 接口。
我有一个包含所有 Mapper.CreateMap<>
的 AutoMapperProfile class
AutoMapperConfig 示例
public class WebApiAutomapperProfile : Profile
{
/// <summary>
/// The configure.
/// </summary>
protected override void Configure()
{
this.CreateMap<Entity, EntityModel>();
}
}
模型接收 IMappingEngine 的原因是一些映射属性内部有其他映射。
在Global.asax(方法Application_Start())我调用:
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();
}
然后每个Controller在构造函数中接收一个IMappingEngine并使用:
MappingEngine.Map<>
型号class样本
public class EntityModel : BaseModel.BaseModel<EntityModel >
{
public EntityModel(IMappingEngine mappingEngine) : base(mappingEngine)
{
}
}
基础模型
public abstract class BaseModel<T> : IBaseModel
where T : class
{
public IMappingEngine MappingEngine { get; set; }
protected BaseModel(IMappingEngine mappingEngine)
{
this.MappingEngine = mappingEngine;
}
}
错误消息说:
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
问题是 IMappingEngine mappingEngine 没有被注入到模型的构造函数中。问题是如何让它发挥作用。
当我尝试执行 .Map
时抛出错误
return this.MappingEngine.Map<Entity,EntityModel>(this.EntityRepository.AllMaterialized().FirstOrDefault());
这是 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)
有什么遗漏或错误吗?
提前致谢!吉列尔莫.
由于您的 EntityController
已由 Simple Injector 正确解析,并且它依赖于 IMapperEngine
,您可以放心映射器引擎已正确注入。可能发生的情况是注册的 Mapper.Engine
在这一点上没有正确初始化,但我只是在猜测。 Automapper 专家应该能够看出这里出了什么问题。
然而,您问题的核心是您尝试对域实体进行依赖注入。看看 this article from Jimmy Bogard(Automapper 的创建者),他解释了为什么这是个坏主意。
一旦您在实体初始化期间不再需要服务依赖项,这个问题就会完全消失。
我开始在我的项目(WebApi2,框架 4.5.1)中使用 AutoMapper(Nuget 的最新版本)并使用 SimpleInjector(Nuget 的最新版本)。
我的问题是我不知道如何配置 SimpleInjector 以通过构造函数将 IMappingEngine 注入我的模型。
现在我收到错误: 未映射的属性:MappingEngine
我正在使用 IMappingEngine 接口。
我有一个包含所有 Mapper.CreateMap<>
的 AutoMapperProfile classAutoMapperConfig 示例
public class WebApiAutomapperProfile : Profile
{
/// <summary>
/// The configure.
/// </summary>
protected override void Configure()
{
this.CreateMap<Entity, EntityModel>();
}
}
模型接收 IMappingEngine 的原因是一些映射属性内部有其他映射。
在Global.asax(方法Application_Start())我调用:
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();
}
然后每个Controller在构造函数中接收一个IMappingEngine并使用:
MappingEngine.Map<>
型号class样本
public class EntityModel : BaseModel.BaseModel<EntityModel >
{
public EntityModel(IMappingEngine mappingEngine) : base(mappingEngine)
{
}
}
基础模型
public abstract class BaseModel<T> : IBaseModel
where T : class
{
public IMappingEngine MappingEngine { get; set; }
protected BaseModel(IMappingEngine mappingEngine)
{
this.MappingEngine = mappingEngine;
}
}
错误消息说:
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
问题是 IMappingEngine mappingEngine 没有被注入到模型的构造函数中。问题是如何让它发挥作用。
当我尝试执行 .Map
时抛出错误return this.MappingEngine.Map<Entity,EntityModel>(this.EntityRepository.AllMaterialized().FirstOrDefault());
这是 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)
有什么遗漏或错误吗?
提前致谢!吉列尔莫.
由于您的 EntityController
已由 Simple Injector 正确解析,并且它依赖于 IMapperEngine
,您可以放心映射器引擎已正确注入。可能发生的情况是注册的 Mapper.Engine
在这一点上没有正确初始化,但我只是在猜测。 Automapper 专家应该能够看出这里出了什么问题。
然而,您问题的核心是您尝试对域实体进行依赖注入。看看 this article from Jimmy Bogard(Automapper 的创建者),他解释了为什么这是个坏主意。
一旦您在实体初始化期间不再需要服务依赖项,这个问题就会完全消失。