Automapper,泛型,DTO funtimes [英] Automapper, generics, dto funtimes

查看:147
本文介绍了Automapper,泛型,DTO funtimes的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里的交易:

我有一个报表设计,用户可以根据一些预定义的数据集创建报表。他们可以选择一组列在报告中包括,然后,当报告奔去,一个IList是到使用automapper的DTO类集合映射NHibernate的集合创建。

I have a report designer where users can create reports based on some predefined datasets. They can select a set of columns to include in the report and then, when the report is ran, an IList is created by mapping the NHibernate collection over to the dto class collection using automapper.

这里的问题是,DTO集合具有在,因为它会与所有的数据填充不管是否需要它的冗余列的一个负载。

The problem with this is that the DTO collection has a load of redundant columns in as it will be populated with all the data regardless of whether or not it's needed.

我解决这个?为什么不能在运行时创建一个DTO类型,使用我们的资料,并只使用所需要的性能NHibernate的集合映射到动态创建的DTO系列:

My solution to this? Why not create a DTO type at runtime, using the information we have and map the nhibernate collection to the dynamically created DTO collection using only the properties needed:

#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);



这个问题?

The problem?

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

我们不能将新起来使用生成的类型作为泛型参数一个IList:■

We can't new up an IList using the generated type as the generic parameter :s

我似乎总是遇到这样的问题。我是不是滥用仿制药?这可能吗?它将使应用程序快很多(一次高速缓存和一些检查,以dissalow临时组装再生等加入),并少了很多繁琐的维护。

I seem to always run into problems like this. Am I abusing generics? Is this possible? It would make the app a lot faster (once caching and some checks to dissalow the temp assembly to be regenerated etc are added) and a lot less fussy to maintain.

W¯¯ ://

使用生成的类型作为泛型参数我们不能向上甲肾上腺素一个IList:■

We can't ne up an IList using the generated type as the generic parameter :s

我似乎总是遇到这样的问题。我是不是滥用仿制药?这可能吗?它将使应用程序快很多(一次高速缓存和一些检查,以dissalow临时组装再生等加入),并少了很多繁琐的维护。

I seem to always run into problems like this. Am I abusing generics? Is this possible? It would make the app a lot faster (once caching and some checks to dissalow the temp assembly to be regenerated etc are added) and a lot less fussy to maintain.

W¯¯ ://

推荐答案

明白了!

不叫createmap !传递泛型列表

dont call createmap passing the generic lists!

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



整理!!

sorted!!

:)

W://

这篇关于Automapper,泛型,DTO funtimes的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆