c# 动态生成继承类并实现序列化特性

项目来源

App传过来的字段是动态的,希望能保证扩展性,返回时,把所需要的字段与数据融合后再返回过去

数据是第3方来源的,但是序列化后的结果又希望能并列返回

如:App传过来 一个设备Id,客户Id等信息(该信息不定,特定的窗口传过来的字段值不同,如一个hash表)

返回的结果是一个地址(省,市,县等字段)(再merge 设备id,客户id等字段)

简单的结果集可以用 字典来返回,但是复杂的结果集就不适合了(代码必须相对优雅)

 

解决方案: 将传过来的字段保存到字典里,然后 生成动态类继承数据类,并将字典数据一一对应到动态类的字段里.

1.原始类

 public class Address
    {
        [JsonProperty(PropertyName = "province"), Description("省份")]
        public string Province { get; set; }

        [JsonProperty(PropertyName = "city"), Description("城市")]
        public string City { get; set; }
    }

 

2.动态扩展该类(增加一个id属性,和一个 县市 属性)

 var assemblyName = new AssemblyName("DynamicProxy");
            var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName,
                AssemblyBuilderAccess.RunAndSave);
            var moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule", "DynamicProxy.dll");
            //定义公开,继承Object,无接口的类
            var typeBuilder = moduleBuilder.DefineType("AddressAddtional", TypeAttributes.Public | TypeAttributes.Serializable, typeof(Address), new Type[0]);
          

            var fieldId = typeBuilder.DefineField("id", typeof(int), FieldAttributes.Private);
            var fieldName = typeBuilder.DefineField("county", typeof(string), FieldAttributes.Private);
            var methodGetId = typeBuilder.DefineMethod("GetId", MethodAttributes.Public, typeof(int), null);
            var methodSetId = typeBuilder.DefineMethod("SetId", MethodAttributes.Public, null, new Type[] { typeof(int) });
            var ilGetId = methodGetId.GetILGenerator();
            ilGetId.Emit(OpCodes.Ldarg_0);//this 入栈
            ilGetId.Emit(OpCodes.Ldfld,fieldId);
            ilGetId.Emit(OpCodes.Ret);
            var ilSetId = methodSetId.GetILGenerator();
            ilSetId.Emit(OpCodes.Ldarg_0);//this 入栈
            ilSetId.Emit(OpCodes.Ldarg_1);//参数 入栈
            ilSetId.Emit(OpCodes.Stfld, fieldId);
            ilSetId.Emit(OpCodes.Ret);

            var methodGetCounty = typeBuilder.DefineMethod("GetCounty", MethodAttributes.Public, typeof(string), null);
            var methodSetCounty = typeBuilder.DefineMethod("SetCounty", MethodAttributes.Public, null, new Type[] { typeof(string) });
            var ilGetCounty = methodGetCounty.GetILGenerator();
            ilGetCounty.Emit(OpCodes.Ldarg_0);//this 入栈
            ilGetCounty.Emit(OpCodes.Ldfld, fieldName);
            ilGetCounty.Emit(OpCodes.Ret);
            var ilSetCounty = methodSetCounty.GetILGenerator();
            ilSetCounty.Emit(OpCodes.Ldarg_0);//this 入栈
            ilSetCounty.Emit(OpCodes.Ldarg_1);//参数 入栈
            ilSetCounty.Emit(OpCodes.Stfld, fieldName);
            ilSetCounty.Emit(OpCodes.Ret);

            var propertyId = typeBuilder.DefineProperty("Id", PropertyAttributes.None, typeof (int), null);
            CustomAttributeBuilder customAttributeBuilder = new CustomAttributeBuilder(typeof(DescriptionAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { "地址Id" });
            CustomAttributeBuilder customAttributeBuilder2 = new CustomAttributeBuilder(typeof(JsonPropertyAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { "id" });
            propertyId.SetCustomAttribute(customAttributeBuilder);//字段描述 
            propertyId.SetCustomAttribute(customAttributeBuilder2);//JsonProperty 
            propertyId.SetGetMethod(methodGetId);
            propertyId.SetSetMethod(methodSetId);

            var propertyCounty = typeBuilder.DefineProperty("County", PropertyAttributes.None, typeof(string), null);
            customAttributeBuilder = new CustomAttributeBuilder(typeof(DescriptionAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { "县区" });
            customAttributeBuilder2 = new CustomAttributeBuilder(typeof(JsonPropertyAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { "county" });
            propertyCounty.SetCustomAttribute(customAttributeBuilder);//字段描述 
            propertyCounty.SetCustomAttribute(customAttributeBuilder2);//JsonProperty 
            propertyCounty.SetGetMethod(methodGetCounty);
            propertyCounty.SetSetMethod(methodSetCounty);
           
            

            var dynamicType = typeBuilder.CreateType();
            assemblyBuilder.Save("DynamicProxy.dll");
          

            instance = Activator.CreateInstance(dynamicType);
            instance.Id = 1001;
            instance.County = "天河区";
            instance.Province = "广东省";
            instance.City = "广州市";
           Console.WriteLine(JsonHelper.ToJson(instance) );
            #endregion

 

3.动态生成的dll,代码如下(使用ILSpy查看)

public class AddressAddtional : Address
{
    private int id;
    private string county;
    [JsonProperty("id"), Description("地址Id")]
    public int Id
    {
        get
        {
            return this.id;
        }
        set
        {
            this.id = value;
        }
    }
    [JsonProperty("county"), Description("县区")]
    public string County
    {
        get
        {
            return this.county;
        }
        set
        {
            this.county = value;
        }
    }
    
}

 

4.执行结果为

 

 

posted @ 2017-06-05 09:18  zslm___  阅读(3708)  评论(1编辑  收藏  举报