private MetaType BuildType(MetaType originalMetaType, Type baseType, Func <Type, MetaType> metaTypeBuilder, string uniqueTypeSuffix, Dictionary <Type, IGrouping <Type, MemberInfo> > members) { var typeBeingTransformed = originalMetaType.Type; var typeName = _namespace + "." + typeBeingTransformed.Name + uniqueTypeSuffix; var typeBuilder = _module.DefineType(typeName, ProjectionTypeAttributes, baseType); // define fields which are members of this projection in the new type, with the same type and name as members in the original IGrouping <Type, MemberInfo> membersForThisType; if (members.TryGetValue(typeBeingTransformed, out membersForThisType)) { foreach (var mi in membersForThisType) { DefineField(mi, typeBuilder); } } var type = typeBuilder.CreateType(); // build protobuf meta type var metaType = metaTypeBuilder(type); metaType.UseConstructor = false; // copy ValueMembers contained in the var originalMetaTypeFields = originalMetaType.GetFields().ToDictionary(vm => vm.Name); if (membersForThisType != null) { foreach (var memberInfo in membersForThisType) { ValueMember originalValueMember; if (originalMetaTypeFields.TryGetValue(memberInfo.Name, out originalValueMember) == false) { throw new ArgumentException(string.Format("The projection contains a member {0} which is not a proto member. This can hide logic behind property which is currently not supported", memberInfo.Name)); } metaType.AddFieldCopy(originalValueMember); } } if (originalMetaType.HasSubtypes == false) { return(metaType); } foreach (var originalSubtype in originalMetaType.GetSubtypes()) { var s = originalSubtype; Func <Type, MetaType> builder = t => metaType.AddSubType(s.FieldNumber, t, s.GetDataFormat()); BuildType(originalSubtype.DerivedType, type, builder, uniqueTypeSuffix, members); } return(metaType); }
static IEnumerable <ValueMember> Visit(MetaType metaType) { do { var fields = metaType.GetFields(); for (int i = 0, n = fields.Length; i < n; i++) { yield return(fields[i]); } }while ((metaType = metaType.BaseType) != null); }
/// <summary> /// Return true if the <paramref name="metaType"/> already defines a field for the specified <paramref name="memberInfo"/> /// </summary> /// <param name="metaType"></param> /// <param name="memberInfo"></param> /// <returns></returns> private static bool ContainsMemberInfo(MetaType metaType, MemberInfo memberInfo) { foreach (var field in metaType.GetFields()) { if (field.Member == memberInfo) { return(true); } } return(false); }
public static void IncludeParents(this RuntimeTypeModel model, ITypeIdentifier typeIdentifier, MetaType type) { if (type.Type.BaseType == typeof(object) || type.Type.BaseType == null) { return; } var metaBase = model.Add(type.Type.BaseType, true); model.IncludeParents(typeIdentifier, metaBase); if (IsRegisteredType(typeIdentifier, type) || IsRegisteredGenericType(typeIdentifier, type)) { foreach (var field in metaBase.GetFields()) { if (!type.GetFields().Select(x => x.FieldNumber).Contains(field.FieldNumber)) { type.AddField(field.FieldNumber, field.Member.Name); } } } }
private static void AddMassiveTransitTypes() { _protobufModel = RuntimeTypeModel.Default; //Right order... AddTypeToModel <AddPeerSubscriptionMessage>(); AddTypeToModel <AddPeerMessage>(); AddTypeToModel <RemovePeerMessage>(); AddTypeToModel <PeerMessage>(); AddTypeToModel <PeerSubscriptionMessage>(); AddTypeToModel <SubscriptionAddedMessage>(); AddTypeToModel <SubscriptionRemovedMessage>(); AddTypeToModel <RemovePeerSubscriptionMessage>(); AddTypeToModel <SubscribeToMessage>(); AddTypeToModel <UnsubscribeFromMessage>(); AddTypeToModel <SubscriptionMessage>(); MetaType metaEnvelope = AddTypeToModel <Envelope>(); //Property 'Message' is a object, we need DynamicType metaEnvelope.GetFields()[6].DynamicType = true; //Compile all types _protobufModel.CompileInPlace(); }
public static MetaType AddRequired(this MetaType metaType, string memberName) { var fieldsCount = metaType.GetFields().Length + metaType.GetSubtypes().Length; return(metaType.AddRequired(fieldsCount + 1, memberName)); }
public static ValueMember GetMember(this MetaType type, string propertyName) => type.GetFields().Single(x => string.Equals(x.Name, propertyName, StringComparison.Ordinal));