[英]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.