简体   繁体   English

自动映射器编译映射

[英]Automapper Compile Mappings

We use automapper with ASP.NET Core 2.0. 我们将自动映射器与ASP.NET Core 2.0结合使用。

We like to create a mapping configuration once, which will be used from each mapper. 我们希望一次创建一个映射配置,该配置将在每个映射器中使用。 We create a mapper per request that we will not have problems because I read once automapper is not thread safe. 我们为每个请求创建一个映射器,因为我们了解到一旦自动映射器不是线程安全的,我们将不会遇到任何问题。

We like to precompile the mappingconfiguration at application startup (See in Code MapperConfigruation.CompileMappings(); 我们希望在应用程序启动时预编译映射配置(请参见代码MapperConfigruation.CompileMappings();)。

If I measure the time how long the mapping takes, i see that the first mapping need more time than the other mappings. 如果我测量映射所花费的时间,我会看到第一个映射比其他映射需要更多的时间。 Is there a reason for that or do I have bug? 是否有原因或我有错误?

Code

In ConfigureService of Startup class: 在启动类的ConfigureService中:

 services.AddSingleton<MyMapperConfiguration>();
 services.AddScoped<IObjectMapper, MyMapper>();     

Mapperconfiguration Mapperconfiguration

public class MyMapperConfiguration
    {
        public MapperConfiguration MapperConfiguration { get; private set; }

        public MappingDefinition MappingDefinition { get; }

        public MapperConfiguration(IOptions<MappingDefinition> mappings)
        {
            // MappingDefinitions hold some information where to search mappings  
            MappingDefinition = mappings.Value;
        }


        public void Configure()
        {
            List<Type> mappingDefinitionClasses = new List<Type>();

             // Search Types with special attribute and add it to the typelist

            MapperConfiguration = new MapperConfiguration(cfg =>
            {
                cfg.AddProfiles(mappingDefinitionClasses.ToArray());
            });            
            MapperConfiguration.CompileMappings(); // <-- THIS SHOULD COMPILE THE MAPPING I THNIK?!

        }

` `

Mapper 映射器

 public class MyMapper : IObjectMapper
    {      
        public IMapper Mapper { get; }

        public Mapper(MapperConfiguration mappingConfiguration)
        {           
            Mapper = mappingConfiguration.MapperConfiguration.CreateMapper();
        }

        public TDestination Map<TSource, TDestination>(TSource source)
        {
            return Mapper.Map<TSource, TDestination>(source);
        }
    }

IObjectMapper: IObjectMapper:

   public interface IObjectMapper
    {        
        TDestination Map<TSource, TDestination>(TSource source);        
    }

Measure time inside a webApi 测量webApi内的时间

Stopwatch sw = new Stopwatch();
sw.Start();
destObj = _mapper.Map<Source, Destination>(sourceObj);
sw.Stop();
Debug.WriteLine($"Duration of mapping: {sw.ElapsedMilliseconds}");

In the Configruate methode of Startup I also get an instance of the mapping configuration and call Configure() that this instance lifes. 在启动的Configruate方法中,我还获得了映射配置的实例,并调用该实例有效的Configure()。

AM is thread safe. AM是线程安全的。 The mapper itself is not expensive, you can share it or not. 映射器本身并不昂贵,您可以共享与否。 It does allocate a few things, so it's cheaper to share it if you can. 它确实分配了一些东西,因此如果可以的话,共享它会更便宜。 CompileMappings changed a bit, so upgrade to the latest. CompileMappings有所更改,因此请升级到最新版本。 But other than that, it's probably the JIT compiler you're seeing. 但是除此之外,您可能正在使用的是JIT编译器。 Until the mapping is executed, the code doesn't get compiled. 在执行映射之前,不会编译代码。 CompileMappings just compiles an expression to IL. CompileMappings只是将表达式编译为IL。 The JIT compiles IL to machine code. JIT将IL编译为机器代码。 You can profile and verify what happens. 您可以分析并验证会发生什么。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM