[英]Automapper, generics, dto funtimes
這是交易:
我有一個報表設計器,用戶可以根據某些預定義的數據集創建報表。 他們可以選擇要包含在報表中的一組列,然后在運行報表時,通過使用automapper將NHibernate集合映射到dto類集合來創建IList。
這樣做的問題是DTO集合中有一堆冗余列,因為它將填充所有數據,無論是否需要它。
我的解決方案? 為什么不在運行時使用我們擁有的信息創建DTO類型,並僅使用所需的屬性將nhibernate集合映射到動態創建的DTO集合:
#region create a dto type:
AssemblyName assemblyName = new AssemblyName();
assemblyName.Name = "tmpAssembly";
var assemblyBuilder = System.Threading.Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
ModuleBuilder module = assemblyBuilder.DefineDynamicModule("tmpModule");
// create a new type builder
TypeBuilder typeBuilder = module.DefineType("ReportDto", TypeAttributes.Public | TypeAttributes.Class);
foreach (var propertyName in propNames)
{
// Generate a private field
FieldBuilder field = typeBuilder.DefineField("_" + propertyName, typeof(string), FieldAttributes.Private);
// Generate a public property
PropertyBuilder property =
typeBuilder.DefineProperty(propertyName,
PropertyAttributes.None,
typeof(string),
new Type[] { typeof(string) });
// The property set and property get methods require a special set of attributes:
MethodAttributes GetSetAttr =
MethodAttributes.Public |
MethodAttributes.HideBySig;
// Define the "get" accessor method for current private field.
MethodBuilder currGetPropMthdBldr =
typeBuilder.DefineMethod("get_value",
GetSetAttr,
typeof(string),
Type.EmptyTypes);
// Intermediate Language stuff...
ILGenerator currGetIL = currGetPropMthdBldr.GetILGenerator();
currGetIL.Emit(OpCodes.Ldarg_0);
currGetIL.Emit(OpCodes.Ldfld, field);
currGetIL.Emit(OpCodes.Ret);
// Define the "set" accessor method for current private field.
MethodBuilder currSetPropMthdBldr =
typeBuilder.DefineMethod("set_value",
GetSetAttr,
null,
new Type[] { typeof(string) });
// Again some Intermediate Language stuff...
ILGenerator currSetIL = currSetPropMthdBldr.GetILGenerator();
currSetIL.Emit(OpCodes.Ldarg_0);
currSetIL.Emit(OpCodes.Ldarg_1);
currSetIL.Emit(OpCodes.Stfld, field);
currSetIL.Emit(OpCodes.Ret);
// Last, we must map the two methods created above to our PropertyBuilder to
// their corresponding behaviors, "get" and "set" respectively.
property.SetGetMethod(currGetPropMthdBldr);
property.SetSetMethod(currSetPropMthdBldr);
}
Type generetedType = typeBuilder.CreateType();
// Now we have our type. Let's create an instance from it:
object generetedObject = Activator.CreateInstance(generetedType);
#endregion
Mapper.CreateMap(typeof(MainInvoiceDataSums), generetedType);
var dto =
Mapper.Map<IList<MainInvoiceDataSums>, IList<generetedType>>(r);
問題?
var dto =
Mapper.Map<IList<MainInvoiceDataSums>, IList<generetedType>>(r);
我們不能使用生成的類型作為泛型參數來新建IList:s
我似乎總是遇到這樣的問題。 我在濫用仿制葯嗎? 這可能嗎? 它會使應用程序更快(一旦緩存和一些檢查以消除重新生成的臨時程序集等)並且更難以維護。
女://
我們不能使用生成的類型作為泛型參數來建立IList:s
我似乎總是遇到這樣的問題。 我在濫用仿制葯嗎? 這可能嗎? 它會使應用程序更快(一旦緩存和一些檢查以消除重新生成的臨時程序集等)並且更難以維護。
女://
得到它了!!
不要調用createmap傳遞通用列表!
MethodInfo createMap = createMapInfo.MakeGenericMethod(new Type[] { typeof(MainInvoiceDataSums), generetedType });
分類!
:)
女://
為什么不使用非泛型版本的Map?
Mapper.Map(r, typeof(IList<MainInvoiceDataSums>),
typeof(IList<>).MakeGenericType(new [] { generatedType });
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.