static Type GenerateSerializer(Type objType) { Type returnType; if (CachedType.TryGetValue(objType, out returnType)) { return(returnType); } var genericType = SerializerType.MakeGenericType(objType); var newTypeName = objType.Name + "Serializer"; var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly( new AssemblyName(newTypeName + "Class") { Version = new Version(1, 0, 0, 0) }, AssemblyBuilderAccess.RunAndSave); var module = assembly.DefineDynamicModule(newTypeName + ".dll"); var type = module.DefineType(newTypeName, TypeAttributes.Public | TypeAttributes.Serializable | TypeAttributes.Sealed, typeof(Object), new[] { genericType }); var methodSerialize = type.DefineMethod("ISerializer.Serialize", MethodAttribute, ByteArrayType, new[] { objType }); var methodDeserialize = type.DefineMethod("ISerializer.Deserialize", MethodAttribute, objType, new[] { ByteArrayType }); var methodDeserializeStream = type.DefineMethod("ISerializer.Deserialize", MethodAttribute, objType, new[] { StreamType }); var methodSerializeStream = type.DefineMethod("ISerializer.Serialize", MethodAttribute, VoidType, new[] { objType, StreamType }); var methodSerializeIL = methodSerialize.GetILGenerator(); var methodDeserializeIL = methodDeserialize.GetILGenerator(); var methodDeserializeStreamIL = methodDeserializeStream.GetILGenerator(); var methodSerializeStreamIL = methodSerializeStream.GetILGenerator(); var bufferLocal = methodSerializeIL.DeclareLocal(BufferStreamType); var bufferStreamLocal = methodSerializeStreamIL.DeclareLocal(BufferStreamType); var returnLocal = methodDeserializeIL.DeclareLocal(objType); var startIndexLocal = methodDeserializeIL.DeclareLocal(typeof(int)); methodDeserializeIL.Emit(OpCodes.Ldc_I4_0); methodDeserializeIL.Emit(OpCodes.Stloc, startIndexLocal.LocalIndex); var returnLocalStream = methodDeserializeStreamIL.DeclareLocal(objType); var startIndexLocalStream = methodDeserializeStreamIL.DeclareLocal(typeof(int)); methodDeserializeStreamIL.Emit(OpCodes.Ldc_I4_0); methodDeserializeStreamIL.Emit(OpCodes.Stloc, startIndexLocalStream.LocalIndex); //Serialize methodSerializeIL.Emit(OpCodes.Newobj, BufferStreamCtor); methodSerializeIL.Emit(OpCodes.Stloc, bufferLocal.LocalIndex); GenerateSerializerCallClassMethod(type, methodSerializeIL, objType, bufferLocal.LocalIndex); methodSerializeIL.Emit(OpCodes.Ldloc, bufferLocal.LocalIndex); methodSerializeIL.Emit(OpCodes.Callvirt, BufferStreamToArrayMethod); methodSerializeIL.Emit(OpCodes.Ret); //SerializeStream methodSerializeStreamIL.Emit(OpCodes.Ldarg_2); methodSerializeStreamIL.Emit(OpCodes.Newobj, BufferStreamStreamCtor); methodSerializeStreamIL.Emit(OpCodes.Stloc, bufferStreamLocal.LocalIndex); GenerateSerializerCallClassMethod(type, methodSerializeStreamIL, objType, bufferStreamLocal.LocalIndex); methodSerializeStreamIL.Emit(OpCodes.Ret); //Deserialize GenerateDeserializerCallClassMethod(type, methodDeserializeIL, objType, returnLocal.LocalIndex, startIndexLocal.LocalIndex); methodDeserializeIL.Emit(OpCodes.Ldloc_S, returnLocal.LocalIndex); methodDeserializeIL.Emit(OpCodes.Ret); //DeserializeStream GenerateDeserializerCallClassMethod(type, methodDeserializeStreamIL, objType, returnLocalStream.LocalIndex, startIndexLocalStream.LocalIndex, useStream: true); methodDeserializeStreamIL.Emit(OpCodes.Ldloc, returnLocalStream.LocalIndex); methodDeserializeStreamIL.Emit(OpCodes.Ret); //Override interface implementation type.DefineMethodOverride(methodSerialize, genericType.GetMethod("Serialize", new[] { objType })); type.DefineMethodOverride(methodDeserialize, genericType.GetMethod("Deserialize", new[] { ByteArrayType })); type.DefineMethodOverride(methodDeserializeStream, genericType.GetMethod("Deserialize", new[] { StreamType })); type.DefineMethodOverride(methodSerializeStream, genericType.GetMethod("Serialize", new[] { objType, StreamType })); returnType = type.CreateType(); CachedType[objType] = returnType; if (BinarySerializer.GenerateAssembly) { assembly.Save(newTypeName + ".dll"); } return(returnType); }