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, IList>(r); 

问题?

 var dto = Mapper.Map<IList, IList>(r); 

我们不能使用生成的类型作为generics参数来新建IList:s

我似乎总是遇到这样的问题。 我在滥用仿制药吗? 这可能吗? 它会使应用程序更快(一旦缓存和一些检查以消除重新生成的临时程序集等)并且更难以维护。

女://

我们不能使用生成的类型作为generics参数来建立IList:s

我似乎总是遇到这样的问题。 我在滥用仿制药吗? 这可能吗? 它会使应用程序更快(一旦缓存和一些检查以消除重新生成的临时程序集等)并且更难以维护。

女://

得到它了!!

不要调用createmap传递通用列表!

 MethodInfo createMap = createMapInfo.MakeGenericMethod(new Type[] { typeof(MainInvoiceDataSums), generetedType }); 

分类!

🙂

女://

为什么不使用非generics版本的Map?

 Mapper.Map(r, typeof(IList), typeof(IList<>).MakeGenericType(new [] { generatedType });