天天看點

AutoMapper之自定義解析

自定義解析

4.自定義解析

AutoMapper可以通過名稱比對等規則進行對象的映射,但是在實際的項目中,隻是這樣是遠遠不夠的,比說我們需要名稱不同的字段進行映射,或者需要再加一些邏輯處理。AutoMapper為此提供一種方案:自定義解析。

4.1示例

我們先對類Source中Value1和Value2進行求和運算,再映射到類Destination中Total。

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

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

AutoMapper提供了接口IValueResolver實作自定義解析,其中包含有源類型,源對象,目标類型,目标對象等資訊。

//IValueResolver接口
public interface IValueResolver<in TSource, in TDestination, TDestMember>
{
	TDestMember Resolve(TSource source, TDestination destination, TDestMember destMember, ResolutionContext context);
}
           

在這裡我們需要繼承這個接口,就可以實作自定義解析。

//繼承接口IValueResolver 
/// <summary>
/// 自定義解析類
/// </summary>
public class CustomResolver : IValueResolver<Source, Destination, int>
{
    /// <summary>
    /// 自定義解析實作
    /// </summary>
    /// <param name="source">源對象</param>
    /// <param name="destination">目标對象</param>
    /// <param name="member"></param>
    /// <param name="context"></param>
    /// <returns></returns>
    public int Resolve(Source source, Destination destination, int member, ResolutionContext context)
    {
    //邏輯處理 對Value1和Value2進行求和運算
        return source.Value1 + source.Value2;
    }
}

//測試方法
[TestMethod]
public void CustomValResTest()
{
	//初始化映射規則,并調用 CustomResolver自定義解析
    Mapper.Initialize(cfg =>
    cfg.CreateMap<Source, Destination>()
    .ForMember(dest => dest.Total, opt => opt.ResolveUsing<CustomResolver>()));
    Mapper.AssertConfigurationIsValid();

    var source = new Source
    {
        Value1 = 5,
        Value2 = 7
    };
    var result = Mapper.Map<Source, Destination>(source);

    Assert.AreEqual(12,result.Total);  //測試通過
}
           

4.2根據源映射值解析

上一個示例中我們把源對象和目标對象當成參數傳入,這樣就降低了方法的重用性。我們可以把源對象和目标對象用Object代替,傳入源對象的映射源值,這樣可以對映射源值進行邏輯處理。

//繼承接口 IMemberValueResolver
/// <summary>
/// 自定義解析類V2 根據源對象的源映射值解析
/// </summary>
public class CustomResolverV2 : IMemberValueResolver<object, object, int, int>
{
    public int Resolve(object source, object destination, int sourceMember, int destinationMember, ResolutionContext context)
    {
		// logic here
        return sourceMember * 2;            
    }
}

//測試方法
[TestMethod]
public void CustomValResV2Test()
{
    //初始化映射規則,
    Mapper.Initialize(cfg =>
    cfg.CreateMap<Source, Destination>()
    .ForMember(dest => dest.Total, opt => opt.ResolveUsing<CustomResolverV2,int>(src=>src.Value1)));
    //Mapper.AssertConfigurationIsValid();
    var source = new Source
    {
        Value1 = 5,
        //Value2 = 7
    };
    var result = Mapper.Map<Source, Destination>(source);
    Assert.AreEqual(10, result.Total); //測試通過
}