0

我开始使用AutoMapper(Nuget的最新版本)到我的项目(WebApi2,框架4.5.1)和使用SimpleInjector(Nuget的最新版本)。AutoMapper没有实例化使用SimpleInjector和WebApi2的IMappingEngine

我的问题是,我不知道如何配置SimpleInjector以通过构造函数将IMappingEngine注入到模型中。

现在,我得到的错误: 未映射属性:MappingEngine

我使用的IMappingEngine接口。

我有一个AutoMapperProfile类与所有Mapper.CreateMap 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(); 
} 

然后,每个控制器接收在构造一个IMappingEngine和用途:

MappingEngine.Map<> 

模型类样品

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; 
    } 
} 

错误消息说:

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没有被注入到模型的构造。问题是如何使它工作。

当我试图做一个错误时抛出错误。地图

return this.MappingEngine.Map<Entity,EntityModel>(this.EntityRepository.AllMaterialized().FirstOrDefault()); 

,这是堆栈跟踪

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) 

遗漏或错误?

提前致谢!吉列尔莫。

+1

嗨吉列尔莫。 Problaby你的问题只与Automapper和SimpleInjector绑定,WebApi就在旁边。您必须尝试以下方法以便轻松帮助您: 1.准备一个单元测试来解决问题。 2.尝试替换Automapper(例如使用Value Injecter https://valueinjecter.codeplex.com/以确定是否是映射问题)。 3.尝试替换SimpleInjector(例如用Windsor)。 这可能会在你的黑暗中提供一些亮光。 – Apocatastasis

+0

你是否遇到任何异常?如果是这样,请将完整的异常与内部异常和堆栈跟踪一起发布。 – Steven

+0

嗨@Apocatastasis,更改IoC容器不是我的选择,因为我正在为一个已经使用它的更大的“插件系统”做一个“插件系统”。 我知道这是一个映射问题。问题是IMappingEngine mappingEngine没有被注入到模型的构造函数中。问题是如何使它工作。 向上述问题添加了错误说明。 – polonskyg

回答

1

由于您的EntityController已通过简单注射器正确解析,并且取决于IMapperEngine,因此您可以放心确保正确注入映射器引擎。可能发生的情况是,注册的Mapper.Engine在该点没有正确初始化,但我只是在猜测这一点。 Automapper专家应该能够看到这里出了什么问题。

然而,问题的核心是你试图向域实体中进行依赖注入。看一下this article from Jimmy Bogard(Automapper的创建者),他解释了为什么这是一个坏主意。

一旦您在实体初始化过程中停止要求服务依赖性,此问题将完全消失。

+0

嗯......那些是Dto类,而不是域类,不知道它是否是相同的情况......无论如何将阅读该文章... thx – polonskyg

+0

@polonskyg:对于DTO同样的事情持有,但我会说的论点更强大。虽然实体可以使用服务(当应用领域驱动设计时),但DTO应该不包含任何逻辑(因为某种原因,它们被称为*** Data **传输对象*),所以向它们注入依赖关系是一个真正的大事不,不。 – Steven

+1

我给了它另一个想法,我认为你是对的,为什么在映射中有IMappingEngine?这是一个现在,控制器将负责将实体转换为Dtos和接收IMappingEngine的实体。谢谢! – polonskyg

相关问题