當我一直在玩和學習ASP.Net MVC 3時,我一直在使用AutoMapper來映射我的域的實體和我的視圖模型。使用反射來雙向自動映射所有域實體以查看MVC3中的模型
我厭倦了爲實現的每個ViewModel單獨創建地圖。因此,我編寫了一些代碼來掃描我的程序集,並使用一些反射來創建每個必需的映射。但是,因爲我對使用AutoMapper的最佳實踐並不十分熟悉,所以我想我可能會向大家展示我所做的事情,並詢問我的方法是否可能會回來咬我。
基本上我有一個叫AutoMappingConfigurator(在Global.asax.cs中使用)類,如下所示:
public static class AutoMappingConfigurator
{
public static void Configure(Assembly assembly)
{
var autoMappingTypePairingList = new List<AutoMappingTypePairing>();
foreach (Type t in assembly.GetTypes())
{
var autoMapAttribute = t
.GetCustomAttributes(typeof(AutoMapAttribute), true)
.OfType<AutoMapAttribute>()
.FirstOrDefault();
if (autoMapAttribute != null)
{
autoMappingTypePairingList
.Add(new AutoMappingTypePairing(autoMapAttribute.SourceType, t));
}
}
autoMappingTypePairingList
.ForEach(mappingPair => mappingPair.CreateBidirectionalMap());
}
}
從本質上講它做什麼,是掃描已標有AutoMapAttribute所有類型的組件併爲每個發現它創建一個雙向映射。
AutoMapAttribute是我創建的一個簡單屬性(基於我在線上找到的示例),我附加到ViewModel以指示映射到哪個Domain Entity。
例如。
[AutoMap(typeof(Project))]
public class ProjectDetailsViewModel
{
public int ProjectId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
關於雙向映射,在我的MVC3工作到目前爲止,我還發現,我經常似乎需要從實體映射到視圖模型的HTTPGET和視圖模型到實體的HttpPost 。
雙向映射爲一個擴展方法實現如下:
public static void CreateBidirectionalMap(this AutoMappingTypePairing mappingPair)
{
Mapper.CreateMap(mappingPair.SourceType, mappingPair.DestinationType)
.IgnoreProperties(mappingPair.DestinationType);
Mapper.CreateMap(mappingPair.DestinationType, mappingPair.SourceType)
.IgnoreProperties(mappingPair.SourceType);
}
關於IgnoreProperties擴展方法,我發現每當我有過,我想忽略的屬性視圖模型(比如當我視圖模型有一個下拉列表,不是基礎域實體的一部分)我似乎不得不通過ForMember AutoMapper方法手動創建忽略。所以我創建了另一個屬性來指示哪些屬性被忽略,所以我在AutoMappingConfigurator中的反射代碼可以自動爲我執行此操作。
的IgnoreProperties擴展方法實現爲一個擴展方法如下:
public static IMappingExpression IgnoreProperties(this IMappingExpression expression
, Type mappingType)
{
var propertiesWithAutoMapIgnoreAttribute =
mappingType.GetProperties()
.Where(p => p.GetCustomAttributes(typeof(AutoMapIgnoreAttribute), true)
.OfType<AutoMapIgnoreAttribute>()
.Count() > 0);
foreach (var property in propertiesWithAutoMapIgnoreAttribute)
{
expression.ForMember(property.Name, opt => opt.Ignore());
}
return expression;
}
這一切都讓我寫我的視圖模型如下並將它AutoMapped:
[AutoMap(typeof(EntityClass))]
private class ViewModelClass
{
public int EntityClassId { get; set; }
[AutoMapIgnore]
public IEnumerable<SelectListItem> DropDownItems { get; set; }
}
private class EntityClass
{
public int EntityClassId { get; set; }
}
雖然這工作對我來說,迄今爲止,我擔心由於我對AutoMapper的經驗不足,我可能會反過來咬我。
所以我的問題是:
- 這是一個很好的方法來設置AutoMapper配置我的映射我的域實體和的ViewModels之間 ?
- 有沒有關於AutoMapper的東西,我可能會丟失,這將使這種不好的方法?
- 是連接屬性忽略通過反射和屬性良好 想法?
- 在我的實體和ViewModel之間創建一個雙向映射是個好主意嗎?
您是否嘗試過使用/查看http://automapper.org/? – MikeSW
是的,我已閱讀所有文檔頁面,並通過各種博客瀏覽,看着無數的計算器問題,我只是沒有看到有人在做我正在做的事情......所以我想知道是否有一個之所以如此...... – mezoid
@mezoid你如何處理自定義映射? – shuniar