AutoMapper 使用总结

AutoMapper是干什么用的?

AutoMapper 是一个用在.Net平台上的对象到对象的自动化映射工具。可将一种类型的对象自动转换到另一种类型的对象。

例如将Model对象和DTO对象之间互转操作。

怎么安装使用

可以使用Nuget包工具搜索“AutoMapper”进行安装使用。

官方网站

https://automapper.readthedocs.io/en/latest/Getting-started.html

快速使用

1.配置对象映射关系

2.使用configuration.CreateMapper()生成mapper对象

3.调用mapper.Map(src)方法进行映射。

        public class Source
        {
            public int SomeValue { get; set; }
        }

        public class Destination
        {
            public int SomeValue { get; set; }
        }

            //Configure AutoMapper
            var configuration = new MapperConfiguration(
                cfg=> {
                    cfg.CreateMap<Source, Destination>();
                    });
            configuration.AssertConfigurationIsValid();
            var mapper = configuration.CreateMapper();

            Source source = new Source() { SomeValue = 1 };
            Destination destination = mapper.Map<Source, Destination>(source);
            Console.WriteLine(destination.SomeValue);

一般在哪对AutoMapper进行配置

一个应用程序只需要配置一次。这就意味着最好的配置地方在应用程序启动的地方,如

对于ASP.NET应用程序来说可以放在Global.asax文件中。

怎么测试(验证)映射

当调用方法configuration.AssertConfigurationIsValid()时,AutoMapper会自动对配置进行验证,如果有异常会在编译时弹出。

忽略目标对象不存在的成员

在配置时,在CreateMap方法中传入MemberList的枚举值进行选择是使用源成员或者None。

cfg.CreateMap<ProductDto, Product>(MemberList.None);

嵌套类对象的映射

例我们有源对象OuterSource,它包含一个子对象InnerSource。我们要映射成一个类似的结构对象,目标OuterDest对象包含一个子对象InnerDest,我们只需要在配置时,将父子对象映射都列出来就行了。如下代码:

ublic class OuterSource
{
	public int Value { get; set; }
	public InnerSource Inner { get; set; }
}

public class InnerSource
{
	public int OtherValue { get; set; }
}

public class OuterDest
{
	public int Value { get; set; }
	public InnerDest Inner { get; set; }
}

public class InnerDest
{
	public int OtherValue { get; set; }
}

var config = new MapperConfiguration(cfg => {
    cfg.CreateMap<OuterSource, OuterDest>();
    cfg.CreateMap<InnerSource, InnerDest>();
});
config.AssertConfigurationIsValid();

var source = new OuterSource
	{
		Value = 5,
		Inner = new InnerSource {OtherValue = 15}
	};
var mapper = config.CreateMapper();
var dest = mapper.Map<OuterSource, OuterDest>(source);

dest.Value.ShouldEqual(5);
dest.Inner.ShouldNotBeNull();
dest.Inner.OtherValue.ShouldEqual(15);

自定义类型转换器

如我们拥有一个类

public class Source
{
	public string Value1 { get; set; }
	public string Value2 { get; set; }
	public string Value3 { get; set; }
}

想转换成的目标类是

public class Destination
{
	public int Value1 { get; set; }
	public DateTime Value2 { get; set; }
	public Type Value3 { get; set; }
}

源类对象的成员类型和目标对象的成员类型是不一致的,我们可以使用如下方法。

[Test]
public void Example()
{
    var configuration = new MapperConfiguration(cfg => {
      cfg.CreateMap<string, int>().ConvertUsing(s => Convert.ToInt32(s));
      cfg.CreateMap<string, DateTime>().ConvertUsing(new DateTimeTypeConverter());
      cfg.CreateMap<string, Type>().ConvertUsing<TypeTypeConverter>();
      cfg.CreateMap<Source, Destination>();
    });
    configuration.AssertConfigurationIsValid();

    var source = new Source
    {
        Value1 = "5",
        Value2 = "01/01/2000",
        Value3 = "AutoMapperSamples.GlobalTypeConverters.GlobalTypeConverters+Destination"
    };

    var mapper = configuration.CreateMapper();
    Destination result = mapper.Map<Source, Destination>(source);
    result.Value3.ShouldEqual(typeof(Destination));
}

public class DateTimeTypeConverter : ITypeConverter<string, DateTime>
{
    public DateTime Convert(string source, DateTime destination, ResolutionContext context)
    {
        return System.Convert.ToDateTime(source);
    }
}

public class TypeTypeConverter : ITypeConverter<string, Type>
{
    public Type Convert(string source, Type destination, ResolutionContext context)
    {
          return Assembly.GetExecutingAssembly().GetType(source);
    }
}

自定义值转换器

假设我们想进行如下对象的转换

public class Source
{
	public int Value1 { get; set; }
	public int Value2 { get; set; }
        public string Other {get;set;
}

public class Destination
{
	public int Total { get; set; }
        public string OtherOff {get;set;}
}

已知目标对象的成员值Total=Source.Value1+Source.Value2,并且可以发现Source.Other成员名称和Destination.OtherOff成员名称不一致,AutoMapper就不知道该进行如何转换了。

对于第一种情况我们可以需要定义一个值解释器类

public class CustomResolver : IValueResolver<Source, Destination, int>
{
	public int Resolve(Source source, Destination destination, int member, ResolutionContext context)
	{
        return source.Value1 + source.Value2;
	}
}

对于第二种情况可以直接使用MapFrom方法就行。代码如下:

var configuration = new MapperConfiguration(cfg =>
   cfg.CreateMap<Source, Destination>()
	 .ForMember(dest => dest.Total, opt => opt.MapFrom<CustomResolver>())
         .ForMember(dest => dest.OtherOff, opt => opt.MapFrom(src => src.Other))
);
configuration.AssertConfigurationIsValid();
        

var source = new Source
	{
		Value1 = 5,
		Value2 = 7,
                Other = "ni"
	};

var mapper = configuration.CreateMapper();
var result = mapper.Map<Source, Destination>(source);

result.Total.ShouldEqual(12);

注意事项

源和目标的名称尽量保持一致,否则就需要自己进行配置说明。

更多

AutoMapper还有很多强大并且实用的功能,如自动快速扁平化对象等,去官网发现吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值