public void Register <T>(Action <ObjectMapping <T> > initializer)
        {
            ObjectMapping <T> objectMapping = new ObjectMapping <T>(_registry);

            initializer(objectMapping);
            Register(objectMapping);
        }
        public void Apply <T>(SerializationRegistry registry, ObjectMapping <T> objectMapping)
        {
            Debug.Assert(typeof(T).IsAnonymous());

            // anonymous types have a single non default constructor
            ConstructorInfo constructorInfo = typeof(T).GetConstructors()[0];

            _defaultObjectMappingConvention.Apply(registry, objectMapping);
            objectMapping.MapCreator(constructorInfo);
        }
예제 #3
0
        public void Apply <T>(SerializationRegistry registry, ObjectMapping <T> objectMapping)
        {
            Type type = objectMapping.ObjectType;
            List <MemberMapping <T> > memberMappings = new List <MemberMapping <T> >();

            CborDiscriminatorAttribute?discriminatorAttribute = type.GetCustomAttribute <CborDiscriminatorAttribute>();

            if (discriminatorAttribute != null)
            {
                objectMapping.SetDiscriminator(discriminatorAttribute.Discriminator);
                objectMapping.SetDiscriminatorPolicy(discriminatorAttribute.Policy);
            }

            Type?namingConventionType = type.GetCustomAttribute <CborNamingConventionAttribute>()?.NamingConventionType;

            if (namingConventionType != null)
            {
                INamingConvention?namingConvention = (INamingConvention?)Activator.CreateInstance(namingConventionType);

                if (namingConvention == null)
                {
                    throw new CborException($"Cannot instantiate naming convention {namingConventionType}");
                }

                objectMapping.SetNamingConvention(namingConvention);
            }

            CborLengthModeAttribute?lengthModeAttribute = type.GetCustomAttribute <CborLengthModeAttribute>();

            if (lengthModeAttribute != null)
            {
                objectMapping.SetLengthMode(lengthModeAttribute.LengthMode);
            }

            PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
            FieldInfo[]    fields     = type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

            foreach (PropertyInfo propertyInfo in properties)
            {
                if (propertyInfo.IsDefined(typeof(CborIgnoreAttribute)))
                {
                    continue;
                }

                MethodInfo?getMethod = propertyInfo.GetMethod;

                if (getMethod == null)
                {
                    continue;
                }

                if ((getMethod.IsPrivate || getMethod.IsStatic) && !propertyInfo.IsDefined(typeof(CborPropertyAttribute)))
                {
                    continue;
                }

                MemberMapping <T> memberMapping = new MemberMapping <T>(registry.ConverterRegistry, objectMapping, propertyInfo, propertyInfo.PropertyType);
                ProcessDefaultValue(propertyInfo, memberMapping);
                ProcessShouldSerializeMethod(memberMapping);
                ProcessLengthMode(propertyInfo, memberMapping);
                ProcessRequired(propertyInfo, memberMapping);
                memberMappings.Add(memberMapping);
            }

            foreach (FieldInfo fieldInfo in fields)
            {
                if (fieldInfo.IsDefined(typeof(CborIgnoreAttribute)))
                {
                    continue;
                }

                if ((fieldInfo.IsPrivate || fieldInfo.IsStatic) && !fieldInfo.IsDefined(typeof(CborPropertyAttribute)))
                {
                    continue;
                }

                Type fieldType = fieldInfo.FieldType;

                MemberMapping <T> memberMapping = new MemberMapping <T>(registry.ConverterRegistry, objectMapping, fieldInfo, fieldInfo.FieldType);
                ProcessDefaultValue(fieldInfo, memberMapping);
                ProcessShouldSerializeMethod(memberMapping);
                ProcessLengthMode(fieldInfo, memberMapping);
                ProcessRequired(fieldInfo, memberMapping);

                memberMappings.Add(memberMapping);
            }

            objectMapping.AddMemberMappings(memberMappings);

            ConstructorInfo[] constructorInfos = type.GetConstructors(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);

            ConstructorInfo?constructorInfo = constructorInfos
                                              .FirstOrDefault(c => c.IsDefined(typeof(CborConstructorAttribute)));

            if (constructorInfo != null)
            {
                CborConstructorAttribute?constructorAttribute = constructorInfo.GetCustomAttribute <CborConstructorAttribute>();
                CreatorMapping           creatorMapping       = objectMapping.MapCreator(constructorInfo);
                if (constructorAttribute != null && constructorAttribute.MemberNames != null)
                {
                    creatorMapping.SetMemberNames(constructorAttribute.MemberNames);
                }
            }
            // if no default constructor, pick up first one
            else if (constructorInfos.Length > 0 && !constructorInfos.Any(c => c.GetParameters().Length == 0))
            {
                constructorInfo = constructorInfos[0];
                objectMapping.MapCreator(constructorInfo);
            }

            MethodInfo?methodInfo = type.GetMethods()
                                    .FirstOrDefault(m => m.IsDefined(typeof(OnDeserializingAttribute)));

            if (methodInfo != null)
            {
                objectMapping.SetOnDeserializingMethod(GenerateCallbackDelegate <T>(methodInfo));
            }
            else if (type.GetInterfaces().Any(i => i == typeof(ISupportInitialize)))
            {
                objectMapping.SetOnDeserializingMethod(t => ((ISupportInitialize)t !).BeginInit());
            }

            methodInfo = type.GetMethods()
                         .FirstOrDefault(m => m.IsDefined(typeof(OnDeserializedAttribute)));
            if (methodInfo != null)
            {
                objectMapping.SetOnDeserializedMethod(GenerateCallbackDelegate <T>(methodInfo));
            }
            else if (type.GetInterfaces().Any(i => i == typeof(ISupportInitialize)))
            {
                objectMapping.SetOnDeserializedMethod(t => ((ISupportInitialize)t !).EndInit());
            }

            methodInfo = type.GetMethods()
                         .FirstOrDefault(m => m.IsDefined(typeof(OnSerializingAttribute)));
            if (methodInfo != null)
            {
                objectMapping.SetOnSerializingMethod(GenerateCallbackDelegate <T>(methodInfo));
            }

            methodInfo = type.GetMethods()
                         .FirstOrDefault(m => m.IsDefined(typeof(OnSerializedAttribute)));
            if (methodInfo != null)
            {
                objectMapping.SetOnSerializedMethod(GenerateCallbackDelegate <T>(methodInfo));
            }
        }
        public void Register <T>()
        {
            ObjectMapping <T> objectMapping = new ObjectMapping <T>(_registry);

            Register(objectMapping);
        }