我们在ASP.NET Core 2.0中使用了者 .
我们想创建一次映射配置,将从每个映射器使用 . 我们为每个请求创建一个mapper,我们不会遇到问题,因为我读过一次automapper不是线程安全的 .
我们喜欢在应用程序启动时预编译映射配置(参见Code MapperConfigruation.CompileMappings();
如果我测量映射所花费的时间,我会看到第一个映射比其他映射需要更多的时间 . 是有原因还是我有bug?
Code
In ConfigureService of Startup class:
services.AddSingleton<MyMapperConfiguration>();
services.AddScoped<IObjectMapper, MyMapper>();
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:
public interface IObjectMapper
{
TDestination Map<TSource, TDestination>(TSource source);
}
Measure time inside a webApi
Stopwatch sw = new Stopwatch();
sw.Start();
destObj = _mapper.Map<Source, Destination>(sourceObj);
sw.Stop();
Debug.WriteLine($"Duration of mapping: {sw.ElapsedMilliseconds}");
在Startup的Configruate方法中,我还获得了映射配置的实例,并调用此实例生效的Configure() .
1 回答
AM是线程安全的 . 映射器本身并不昂贵,您可以共享或不共享 . 它确实分配了一些东西,所以如果可以,分享它会更便宜 . CompileMappings改变了一下,所以升级到最新版本 . 但除此之外,它可能是你所看到的JIT编译器 . 在执行映射之前,代码不会被编译 . CompileMappings只是将表达式编译为IL . JIT将IL编译为机器代码 . 您可以分析并验证发生了什么 .