日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java automapper 使用_AutoMapper实际项目运用

發布時間:2024/1/1 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java automapper 使用_AutoMapper实际项目运用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

AutoMapper是對象到對象的映射工具。在完成映射規則之后,AutoMapper可以將源對象轉換為目標對象。

配置AutoMapper映射規則

AutoMapper是基于約定的,因此在實用映射之前,我們需要先進行映射規則的配置。

public class Source

{

public int SomeValue { get; set; }

public string AnotherValue { get; set; }

}

public class Destination

{

public int SomeValue { get; set; }

}

在上面的代碼中,我們定義了兩個類,我們需要將Source類的對象映射到Destination類的對象上面。要完成這個操作,我們需要對AutoMapper進行如下配置:

Mapper.CreateMap();

進行一下測試:

Source src = new Source() { SomeValue = 1, AnotherValue = "2" };

Destination dest = Mapper.Map(src);

ObjectDumper.Write(dest);

我們可以在控制臺看到dest對象的屬性值:

這樣我們就完成了一個簡單的AutoMapper映射。

Profile的用法

Profile提供了一個命名的映射類,所有繼承自Profile類的子類都是一個映射集合。

我們來看一下Profile的用法,這個例子中仍然使用上面的Source類和Destination類。

public class SourceProfile : Profile

{

protected override void Configure()

{

CreateMap();

}

}

我們可以再Profile中重寫Configure方法,從而完成映射規則的配置。從Profile初始化Mapper規則:

Mapper.Initialize(x => x.AddProfile());

在一個Profile中,我們可以完成多個、更復雜的規則的約定:

public class Destination2

{

public int SomeValue { get; set; }

public string AnotherValue2 { get; set; }

}

public class SourceProfile : Profile

{

protected override void Configure()

{

//Source->Destination

CreateMap();

//Source->Destination2

CreateMap().ForMember(d => d.AnotherValue2, opt =>

{

opt.MapFrom(s => s.AnotherValue);

});

}

}

AutoMapper最佳實踐

這段內容將討論AutoMapper的規則寫在什么地方的問題。

在上一段中,我們已經知道了如何使用AutoMapper進行簡單的對象映射,但是,在實際的項目中,我們會有很多類進行映射(從Entity轉換為Dto,或者從Entity轉換為ViewModel等),這么多的映射如何組織將成為一個問題。

首先我們需要定義一個Configuration.cs的類,該類提供AutoMapper規則配置的入口,它只提供一個靜態的方法,在程序第一次運行的時候調用該方法完成配置。

當有多個Profile的時候,我們可以這樣添加:

public class Configuration

{

public static void Configure()

{

Mapper.Initialize(cfg =>

{

cfg.AddProfile();

cfg.AddProfile();

cfg.AddProfile();

});

}

}

在程序運行的時候,只需要調用Configure方法即可。

了解了這些實現以后,我們可以再項目中添加AutoMapper文件夾,文件夾結構如下:

Configuration為我們的靜態配置入口類;Profiles文件夾為我們所有Profile類的文件夾。如果是MVC,我們需要在Global中調用:

AutoMapper.Configuration.Configure();

扁平化映射(Flattening)

默認情況下,我們的Source類和Destination類是根據屬性名稱進行匹配映射的。除此之外,默認的映射規則還有下面兩種情況,我們稱之為扁平化映射,即當Source類中不包含Destination類中的屬性的時候,AutoMapper會將Destination類中的屬性進行分割,或匹配“Get”開頭的方法,例如:

Order類:

public class Order

{

public Customer Customer { get; set; }

public decimal GetTotal()

{

return 100M;

}

}

Order類中包含了一個customer對象和一個GetTotal方法,為了方便演示,我直接將GetTotal方法返回100;

Customer類的定義如下:

public class Customer

{

public string Name { get; set; }

}

OrderDto類的定義如下:

public class OrderDto

{

public string CustomerName { get; set; }

public string Total { get; set; }

}

我們在進行映射的時候,不需要進行特殊的配置,既可以完成從Order到OrderDto的映射。

public class OrderProfile : Profile

{

protected override void Configure()

{

CreateMap();

}

}

測試代碼:

Entity.Customer customer = new Entity.Customer() { Name = "Tom" };

Entity.Order order = new Entity.Order() { Customer = customer };

Dto.OrderDto orderDto = Mapper.Map(order);

ObjectDumper.Write(order, 2);

ObjectDumper.Write(orderDto);

測試結果:

指定映射字段(Projection)

在實際的業務環境中,我們的Source類和Destination類的字段不可能一對一的匹配,這個時候我們就需要來指定他們的實際映射關系,例如:

public class CalendarEvent

{

public DateTime Date { get; set; }

public string Title { get; set; }

}

public class CalendarEventForm

{

public DateTime EventDate { get; set; }

public int EventHour { get; set; }

public int EventMinute { get; set; }

public string DisplayTitle { get; set; }

}

在這兩個類中,CalendarEvent的Date將被拆分為CalendarEventForm的日期、時、分三個字段,Title也將對應DisplayTitle字段,那么相應的Profile定義如下:

public class CalendarEventProfile : Profile

{

protected override void Configure()

{

CreateMap()

.ForMember(dest => dest.EventDate, opt => opt.MapFrom(src => src.Date.Date))

.ForMember(dest => dest.EventHour, opt => opt.MapFrom(src => src.Date.Hour))

.ForMember(dest => dest.EventMinute, opt => opt.MapFrom(src => src.Date.Minute))

.ForMember(dest => dest.DisplayTitle, opt => opt.MapFrom(src => src.Title));

}

}

測試代碼:

Entity.CalendarEvent calendarEvent = new Entity.CalendarEvent()

{

Date = DateTime.Now,

Title = "Demo Event"

};

Entity.CalendarEventForm calendarEventForm = Mapper.Map(calendarEvent);

ObjectDumper.Write(calendarEventForm);

測試結果:

驗證配置項(Configuration Validation)

AutoMapper提供了一種驗證機制,用來判斷Destination類中的所有屬性是否都被映射,如果存在未被映射的屬性,則拋出異常。

驗證的用法:

Mapper.AssertConfigurationIsValid();

例如:

public class Source

{

public int SomeValue { get; set; }

public string AnotherValue { get; set; }

}

Destination代碼:

public class Destination

{

public int SomeValuefff { get; set; }

}

測試:

Mapper.CreateMap();

Mapper.AssertConfigurationIsValid();

運行程序將會出現AutoMapperConfigurationException異常:

這是因為SomeValuefff在Source類中沒有對應的字段造成的。

解決這種異常的方法有:

指定映射字段,例如:

Mapper.CreateMap()

.ForMember(dest => dest.SomeValuefff, opt =>

{

opt.MapFrom(src => src.SomeValue);

});

或者使用Ignore方法:

Mapper.CreateMap()

.ForMember(dest => dest.SomeValuefff, opt =>

{

opt.Ignore();

});

或者使用自定義解析器,自定義解析器在下面講到。

自定義解析器(Custom value resolvers)

AutoMapper允許我們自定義解析器來完成Source到Destination的值的轉換。例如:

public class Source

{

public int Value1 { get; set; }

public int Value2 { get; set; }

}

public class Destination

{

public int Total { get; set; }

}

Total屬性在Source中不存在,如果現在創建映射規則,在映射的時候必然會拋出異常。這個時候我們就需要使用自定義解析器來完成映射。

自定義解析器需要實現 IValueResolver 接口,接口的定義如下:

public interface IValueResolver

{

ResolutionResult Resolve(ResolutionResult source);

}

我們來自定義一個Resolver:

public class CustomResolver : ValueResolver

{

protected override int ResolveCore(Source source)

{

return source.Value1 + source.Value2;

}

}

然后在映射規則中使用這個解析器:

public class SourceProfile : Profile

{

protected override void Configure()

{

//Source->Destination

CreateMap()

.ForMember(dest => dest.Total, opt =>

{

opt.ResolveUsing();

});

}

}

測試代碼:

Source src = new Source()

{

Value1 = 1,

Value2 = 2

};

Destination dest = Mapper.Map(src);

ObjectDumper.Write(dest);

測試結果:

在使用自定義Resolver中,我們還可以指定Resolver的構造函數,例如:

//Source->Destination

CreateMap()

.ForMember(dest => dest.Total, opt =>

{

opt.ResolveUsing()

.ConstructedBy(() =>

new?CustomResolver

());

});

自定義類型轉換器(Custom type converters)

AutoMapper通過ConvertUsing來使用自定義類型轉換器。ConvertUsing有三種用法:

void ConvertUsing(Func mappingFunction);

void ConvertUsing(ITypeConverter converter);

void ConvertUsing() where TTypeConverter : ITypeConverter;

當我們有如下的Source類和Destination類:

public class Source

{

public string Value1 { get; set; }

}

public class Destination

{

public int Value1 { get; set; }

}

我們可以使用如下配置:

public class SourceProfile : Profile

{

protected override void Configure()

{

//string->int

CreateMap()

.ConvertUsing(Convert.ToInt32);

//Source->Destination

CreateMap();

}

}

在上面的配置中,我們首先創建了從string到int的類型轉換,這里使用了系統自帶的Convert.ToInt32轉換方法。

除了這種方法之外,我們還可以自定義類型轉換器:

public class CustomConverter : ITypeConverter

{

public Destination Convert(ResolutionContext context)

{

Source src = context.SourceValue as Source;

Destination dest = new Destination();

dest.Value1 = System.Convert.ToInt32(src.Value1);

return dest;

}

}

通過這個轉換器,我們可以繞過string到int的轉換,直接將Source類的對象轉換為Destination類的對象。

對應的配置如下:

public class SourceProfile : Profile

{

protected override void Configure()

{

//Source->Destination

CreateMap()

.ConvertUsing();

}

}

或者,我們也可以使用下面的配置:

public class SourceProfile : Profile

{

protected override void Configure()

{

//Source->Destination

CustomConverter converter = new CustomConverter();

CreateMap()

.ConvertUsing(converter);

}

}

空值替換(Null substitution)

空值替換允許我們將Source對象中的空值在轉換為Destination的值的時候,使用指定的值來替換空值。

public class Source

{

public string Value { get; set; }

}

public class Destination

{

public string Value { get; set; }

}

配置代碼:

public class SourceProfile : Profile

{

protected override void Configure()

{

//Source->Destination

CreateMap()

.ForMember(dest => dest.Value, opt =>

{

opt.NullSubstitute("原始值為NULL");

});

}

}

測試代碼:

Source src = new Source();

Destination dest = Mapper.Map(src);

ObjectDumper.Write(dest);

測試結果:

條件映射(Conditional mapping)

條件映射只當Source類中的屬性值滿足一定條件的時候才進行映射。例如:

public class Foo

{

public int baz;

}

public class Bar

{

public uint baz;

}

對應的配置代碼如下:

Mapper.CreateMap()

.ForMember(dest => dest.baz, opt =>

{

opt.Condition(src => (src.baz >= 0));

});

總結

以上是生活随笔為你收集整理的java automapper 使用_AutoMapper实际项目运用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。