public TypeBuilder DefineCollectionFormatterType(Type type, Type elementType) { VerifyTypeIsPublic(type); string pre = "Array2."; if (Array1FormatterHelper.IsArray1Type(elementType)) { pre = "Array1."; } Type formatterType = typeof(IBssomFormatter <>).MakeGenericType(type); TypeBuilder typeBuilder = DefineType("Bssom.Formatters." + pre + SubtractFullNameRegex.Replace(type.FullName, string.Empty).Replace(".", "_") + "Formatter" + Interlocked.Increment(ref nameSequence), TypeAttributes.NotPublic | TypeAttributes.Sealed, null, new[] { formatterType }); return(typeBuilder); }
public static TypeInfo BuildICollectionImplementationType(DynamicFormatterAssembly assembly, Type type, ConstructorInfo constructor, Type itemType, bool isImplGenerIList, bool IsImplIList, bool isImplGenerICollec, bool isImplIReadOnlyList) { TypeBuilder typeBuilder = assembly.DefineFormatterType(type); MethodBuilder sizeMethod = TypeBuildHelper.DefineSizeMethod(typeBuilder, type); MethodBuilder serializeMethod = TypeBuildHelper.DefineSerializeMethod(typeBuilder, type); if (itemType == typeof(object)) { //itemType is Object, Array2 if (IsImplIList) { TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SerializeIList), BindingFlags.Public | BindingFlags.Static)); } else { TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SerializeIEnumerable), BindingFlags.Public | BindingFlags.Static)); } TypeBuildHelper.CallOneMethodInSize(sizeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SizeIEnumerable), BindingFlags.Public | BindingFlags.Static)); } else { if (Array1FormatterHelper.IsArray1Type(itemType)) { //Array1 TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array1FormatterHelper).GetMethod(nameof(Array1FormatterHelper.SerializeIEnumerable), new Type[] { typeof(BssomWriter).MakeByRefType(), typeof(BssomSerializeContext).MakeByRefType(), typeof(IEnumerable <>).MakeGenericType(itemType) })); TypeBuildHelper.CallOneMethodInSize(sizeMethod, typeof(Array1FormatterHelper).GetMethod(nameof(Array1FormatterHelper.SizeIEnumerable), new Type[] { typeof(BssomSizeContext).MakeByRefType(), typeof(IEnumerable <>).MakeGenericType(itemType) })); } else { if (isImplGenerIList || isImplIReadOnlyList) { TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SerializeGenerIList), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(itemType)); } else { TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SerializeGenericIEnumerable), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(itemType)); } TypeBuildHelper.CallOneMethodInSize(sizeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SizeGenericIEnumerable), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(itemType)); } } MethodBuilder deserializeMethod = TypeBuildHelper.DefineDeserializeMethod(typeBuilder, type); ParameterInfo[] args = constructor.GetParameters(); if (args.Length == 1 && args[0].ParameterType != typeof(int)) { //new T(IEnumerable t) Type dynamicCacheType = typeof(CollectionDynamicDelegateCache <>).MakeGenericType(type); MethodInfo methodinfo = dynamicCacheType.GetMethod(nameof(CollectionDynamicDelegateCache <int> .GenerateInjectCtor)); methodinfo.Invoke(null, new object[] { constructor, args[0].ParameterType }); TypeBuildHelper.CallDeserializeDelegate(deserializeMethod, type, dynamicCacheType.GetField(nameof(CollectionDynamicDelegateCache <int> .Deserialize), BindingFlags.Public | BindingFlags.Static)); } else { if (itemType == typeof(DateTime))//DateTime需要特殊处理,因为要处理Standrand和Native { Type dtCollBuilder = typeof(DateTimeCollectionDeserializeBuilder <>).MakeGenericType(type); MethodInfo methodinfo = dtCollBuilder.GetMethod(nameof(DateTimeCollectionDeserializeBuilder <ICollection <DateTime> > .ConstructorInit)); methodinfo.Invoke(null, new object[] { constructor }); TypeBuildHelper.CallOneMethodInDeserialize(deserializeMethod, dtCollBuilder.GetMethod(nameof(DateTimeCollectionDeserializeBuilder <ICollection <DateTime> > .Deserialize))); } else { Type dynamicCacheType = typeof(CollectionDynamicDelegateCache <>).MakeGenericType(type); if (args.Length == 0) { MethodInfo methodinfo = dynamicCacheType.GetMethod(nameof(CollectionDynamicDelegateCache <int> .GenerateDeserializeWithEmptyCtor)); methodinfo.Invoke(null, new object[] { constructor, isImplGenerICollec, itemType }); } else { DEBUG.Assert(args.Length == 1 && args[0].ParameterType == typeof(int)); MethodInfo methodinfo = dynamicCacheType.GetMethod(nameof(CollectionDynamicDelegateCache <int> .GenerateDeserializeWithCapacityCtor)); methodinfo.Invoke(null, new object[] { constructor, isImplGenerICollec, itemType }); } TypeBuildHelper.CallDeserializeDelegate(deserializeMethod, type, dynamicCacheType.GetField(nameof(CollectionDynamicDelegateCache <int> .Deserialize), BindingFlags.Public | BindingFlags.Static)); } } return(typeBuilder.CreateTypeInfo()); }
public static TypeInfo BuildICollectionInterfaceType(DynamicFormatterAssembly assembly, Type type, Type elementType) { TypeBuilder typeBuilder = assembly.DefineCollectionFormatterType(type, elementType); MethodBuilder serializeMethod = TypeBuildHelper.DefineSerializeMethod(typeBuilder, type); MethodBuilder deserializeMethod = TypeBuildHelper.DefineDeserializeMethod(typeBuilder, type); MethodBuilder sizeMethod = TypeBuildHelper.DefineSizeMethod(typeBuilder, type); if (type.IsGenericType == false) { DEBUG.Assert(type == typeof(IEnumerable) || type == typeof(IList) || type == typeof(ICollection)); //itemType is Object, Array2 if (type == typeof(IList)) { TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SerializeIList), BindingFlags.Public | BindingFlags.Static)); } else { TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SerializeIEnumerable), BindingFlags.Public | BindingFlags.Static)); } TypeBuildHelper.CallOneMethodInDeserialize(deserializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.DeserializeList), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(typeof(object))); TypeBuildHelper.CallOneMethodInSize(sizeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SizeIEnumerable), BindingFlags.Public | BindingFlags.Static)); } else { Type genericTypeDefine = type.GetGenericTypeDefinition(); DEBUG.Assert(genericTypeDefine == typeof(IEnumerable <>) || genericTypeDefine == typeof(IList <>) || genericTypeDefine == typeof(ICollection <>) || genericTypeDefine == typeof(ISet <>) || genericTypeDefine == typeof(IReadOnlyList <>) || genericTypeDefine == typeof(IReadOnlyCollection <>)); if (Array1FormatterHelper.IsArray1Type(elementType)) { //Array1 TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array1FormatterHelper).GetMethod(nameof(Array1FormatterHelper.SerializeIEnumerable), new Type[] { typeof(BssomWriter).MakeByRefType(), typeof(BssomSerializeContext).MakeByRefType(), typeof(IEnumerable <>).MakeGenericType(elementType) })); if (genericTypeDefine == typeof(ISet <>)) { TypeBuildHelper.CallOneMethodInDeserialize(deserializeMethod, typeof(Array1FormatterHelper).GetMethod(Array1FormatterHelper.DeserializeSetPrefix + elementType.Name, BindingFlags.Public | BindingFlags.Static)); } else { Type listFormatterType = Array1ResolverGetFormatterHelper.GetListFormatterType(elementType); FieldInfo field = listFormatterType.GetField(nameof(DateTimeListFormatter.Instance), BindingFlags.Static | BindingFlags.Public); MethodInfo method = listFormatterType.GetMethod(nameof(DateTimeListFormatter.Deserialize)); TypeBuildHelper.CallOneStaticFieldMethodInDeserialize(deserializeMethod, field, method); } TypeBuildHelper.CallOneMethodInSize(sizeMethod, typeof(Array1FormatterHelper).GetMethod(nameof(Array1FormatterHelper.SizeIEnumerable), new Type[] { typeof(BssomSizeContext).MakeByRefType(), typeof(IEnumerable <>).MakeGenericType(elementType) })); } else { if (genericTypeDefine == typeof(IList <>) || genericTypeDefine == typeof(IReadOnlyList <>)) { TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SerializeGenerIList), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(elementType)); } else { TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SerializeGenericIEnumerable), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(elementType)); } if (genericTypeDefine == typeof(ISet <>)) { TypeBuildHelper.CallOneMethodInDeserialize(deserializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.DeserializeSet), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(elementType)); } else { TypeBuildHelper.CallOneMethodInDeserialize(deserializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.DeserializeList), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(elementType)); } TypeBuildHelper.CallOneMethodInSize(sizeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SizeGenericIEnumerable), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(elementType)); } } return(typeBuilder.CreateTypeInfo()); }