예제 #1
0
        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);
        }
예제 #2
0
 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);
 }
예제 #3
0
 /// <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);
 }
예제 #4
0
        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);
                    }
                }
            }
        }
예제 #5
0
        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();
        }
예제 #6
0
        public static MetaType AddRequired(this MetaType metaType, string memberName)
        {
            var fieldsCount = metaType.GetFields().Length + metaType.GetSubtypes().Length;

            return(metaType.AddRequired(fieldsCount + 1, memberName));
        }
예제 #7
0
 public static ValueMember GetMember(this MetaType type, string propertyName)
 => type.GetFields().Single(x => string.Equals(x.Name, propertyName, StringComparison.Ordinal));