.NET对象映射器TinyMapper性能分析

.NET开发中,对象映射是一个常见的需求,它允许开发者将一个对象的属性或字段映射到另一个对象。TinyMapper是一个轻量级的.NET对象映射器,其主要优势在于性能。本文将介绍如何使用TinyMapper进行对象映射,并对其性能进行分析。

TinyMapper的基本使用

TinyMapper允许开发者轻松地将一个对象映射到另一个对象。例如,可以将Person类的对象映射到PersonDto类的对象。以下是使用TinyMapper进行映射的示例代码:

private static void MapPerson() { TinyMapper.Bind<Person, PersonDto>(); var person = new Person { Id = Guid.NewGuid(), FirstName = "John", LastName = "Doe", Email = "support@tinymapper.net", Address = "Wall Street", CreateTime = DateTime.Now, Nickname = "Object Mapper", Phone = "Call Me Maybe " }; var personDto = TinyMapper.Map<PersonDto>(person); }

在上述代码中,首先绑定了Person类和PersonDto类之间的映射关系,然后创建了一个Person对象,并使用TinyMapper将其映射到PersonDto对象。

性能测试

性能是TinyMapper的一个重要优势。为了验证这一点,使用Person类进行了性能测试,并将TinyMapper与AutoMapper进行了比较。测试代码如下:

private static void MeasureHandwritten() { Person person = CreatePerson(); Stopwatch stopwatch = Stopwatch.StartNew(); for (int i = 0; i < Iterations; i++) { PersonDto personDto = MapHandwritten(person); } stopwatch.Stop(); Console.WriteLine("Handwritten: {0}ms", stopwatch.Elapsed.TotalMilliseconds); } private static void MeasureTinyMapper() { Person person = CreatePerson(); TinyMapper.Bind<Person, PersonDto>(); Stopwatch stopwatch = Stopwatch.StartNew(); for (int i = 0; i < Iterations; i++) { var personDto = TinyMapper.Map<PersonDto>(person); } stopwatch.Stop(); Console.WriteLine("TinyMapper: {0}ms", stopwatch.Elapsed.TotalMilliseconds); } private static void MeasureAutoMapper() { Person person = CreatePerson(); Mapper.CreateMap<Person, PersonDto>(); Stopwatch stopwatch = Stopwatch.StartNew(); for (int i = 0; i < Iterations; i++) { var personDto = Mapper.Map<PersonDto>(person); } stopwatch.Stop(); Console.WriteLine("AutoMapper: {0}ms", stopwatch.Elapsed.TotalMilliseconds); }

在测试中,创建了一个Person类实例,并将其所有属性映射到PersonDto类。重复测量了1,000,000次,以确保结果的准确性。

开始使用TinyMapper

TinyMapper可以通过NuGet包管理器安装。首先,需要绑定源类型和目标类型,如下所示:

TinyMapper.Bind<Person, PersonDto>();

绑定后,TinyMapper就知道如何将Person对象映射到PersonDto对象。最后,调用Map方法,将得到映射后的对象。这是一个完整的示例:

var personDto = TinyMapper.Map<PersonDto>(person);

需要执行两个步骤:

  • 绑定源类型到目标类型
  • 将源对象映射到目标类型

注意:如果是在多线程应用程序中使用TinyMapper,请在应用程序启动时注册所有绑定。在应用程序运行时,只需要调用Map方法。这样,将获得速度和线程安全性。TinyMapper可以为完成第一步,即只需要调用Map方法,结果将是一样的。

注意:在没有调用Bind的情况下调用Map,这不是线程安全的。

更复杂的示例

让来看一个更复杂的示例。例如,有以下类:

public sealed class PersonComplex { public Address Address { get; set; } public DateTime CreateTime { get; set; } public IReadOnlyList<string> Emails { get; set; } public string FirstName { get; set; } public Guid Id { get; set; } public string LastName { get; set; } public string Nickname { get; set; } } public sealed class Address { public string Phone { get; set; } public string Street { get; set; } public string ZipCode { get; set; } }

不想映射CreateTime和Nickname属性。如所见,刚刚将CreateTime和Nickname标记为忽略。绑定LastName从源Surname到目标类,并绑定IList的电子邮件到List。TinyMapper允许:

  • 忽略字段
  • 将一个字段映射到不同的字段
  • 将接口映射到确切的类型

自定义映射

例如,有以下类:

public sealed class PersonCustomSource { public IList<string> Emails { get; set; } public string FirstName { get; set; } public string LastName { get; set; } } public sealed class PersonCustomTarget { public IList<string> Emails { get; set; } public string FullName { get; set; } }

希望将FirstName和LastName映射到FullName,使用以下约定"FirstName LastName"。TinyMapper支持TypeConverter,即可以为任何类型创建自己的TypeConverter。

public sealed class PersonTypeConverter : TypeConverter { public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { return destinationType == typeof(PersonCustomTarget); } public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { var concreteValue = (PersonCustomSource)value; var result = new PersonCustomTarget { FullName = string.Format("{0} {1}", concreteValue.FirstName, concreteValue.LastName), Emails = new List<string>(concreteValue.Emails) }; return result; } }

下一步是注册类型转换器。TypeConverter支持通过属性注册...

[TypeConverter(typeof(PersonTypeConverter))] public sealed class PersonCustomSource { public IList<string> Emails { get; set; } public string FirstName { get; set; } public string LastName { get; set; } }

...或代码:

TypeDescriptor.AddAttributes(typeof(PersonCustomSource), new TypeConverterAttribute(typeof(PersonTypeConverter)));

这是一个额外的示例,展示了如何实现类型转换器。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485