项目来源

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[]); 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 = ;
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.执行结果为

c# 动态生成继承类并实现序列化特性的更多相关文章

  1. 根据数据库记录动态生成C#类及其公共属性并动态执行的解决方案

    原文:根据数据库记录动态生成C#类及其公共属性并动态执行的解决方案 问题: C#中,想动态产生这么一个类: public class StatisticsData    {        public ...

  2. 分析JVM动态生成的类

    总结思考:让jvm创建动态类及其实例对象,需要给它提供哪些信息? 三个方面: 1.生成的类中有哪些方法,通过让其实现哪些接口的方式进行告知: 2.产生的类字节码必须有个一个关联的类加载器对象: 3.生 ...

  3. Java基础---Java---基础加强---类加载器、委托机制、AOP、 动态代理技术、让动态生成的类成为目标类的代理、实现Spring可配置的AOP框架

    类加载器 Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader,AppClassLoader 类加载器也是Jav ...

  4. JAVA基础加强(张孝祥)_类加载器、分析代理类的作用与原理及AOP概念、分析JVM动态生成的类、实现类似Spring的可配置的AOP框架

    1.类加载器 ·简要介绍什么是类加载器,和类加载器的作用 ·Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader ...

  5. Emit动态生成代理类用于监控对象的字段修改

    利用Emit动态生成代理对象监控对象哪些字段被修改,被修改为什么值 被Register的对象要监控的值必须是Virtual虚类型 必须使用CreateInstance创建对象 必须使用DynamicP ...

  6. Java——动态生成POJO类

    package com.java.test.dynamicpojo; import java.io.ByteArrayOutputStream; import java.io.IOException; ...

  7. 动态生成Person类的对象 代码参考

    #include <iostream> #include <string> using namespace std; class Person { private: strin ...

  8. Java中动态代理技术生成的类与原始类的区别 (转)

    用动态代理的时候,对它新生成的类长什么样子感到好奇.有幸通过一些资料消除了心里的疑惑. 平时工作使用的Spring框架里面有一个AOP(面向切面)的机制,只知道它是把类重新生成了一遍,在切面上加上了后 ...

  9. Java中动态代理技术生成的类与原始类的区别

    用动态代理的时候,对它新生成的类长什么样子感到好奇.有幸通过一些资料消除了心里的疑惑. 平时工作使用的Spring框架里面有一个AOP(面向切面)的机制,只知道它是把类重新生成了一遍,在切面上加上了后 ...

随机推荐

  1. Docker学习笔记_进入正在运行的Docker容器

    如何进入正在运行的Docker容器? 这里记录一种方法. 1.先查看container ID,并确认这个容器已经启动 docker ps -a       #列出懿创建的所有容器 docker ps ...

  2. python pipelines 用法

    http://zacstewart.com/2014/08/05/pipelines-of-featureunions-of-pipelines.html http://blog.csdn.net/m ...

  3. select样式调整

    如果select样式如下图:是因为添加了 border-color:#adb7d6; border-width:1px; 样式 删除上面两个样式属性,效果如下图:

  4. git之对比svn

    关于git的发展和历史介绍网上有很多资料,大家可以自行去了解,这里给大家一个传送门git介绍在这里我就不多说了.我们今天本篇文章的定位就是帮助大家来了解一下关于git和svn之间的区别及git的安装. ...

  5. jstl c

    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> 例子:list中有两 ...

  6. Build fat static library (device + simulator) using Xcode and SDK 4+

    155down votefavorite 185 It appears that we can - theoretically - build a single static library that ...

  7. Jquery Call ,apply,callee

    //call function A() { name = "abc"; this.ShowName = function (val) { alert(name + ",& ...

  8. 使用CodeMaid自动程序排版[转]

    前言 「使用StyleCop验证命名规则」这篇文章,指引开发人员透过StyleCop这个工具,来自动检验项目中产出的程序代码是否合乎命名规则. [Tool] 使用StyleCop验证命名规则 但是在项 ...

  9. C#Async,await异步简单介绍

    C# 5.0 引入了async/await,.net framework4.5开始支持该用法 使用: 由async标识的方法必须带有await,如果不带await,方法将被同步执行 static vo ...

  10. 利用find同时查找多种类型文件

    find . -name "*.c" -o -name "*.cpp" -o -name "*.h" 就可以列出当前目录下面所有的c,cpp ...