private MessagePart ParameterizedMessageTypeTest(Type messageType) { PropertyInfo field = messageType.GetProperty("OptionalInt", BindingFlags.NonPublic | BindingFlags.Instance); MessagePartAttribute attribute = field.GetCustomAttributes(typeof(MessagePartAttribute), true).OfType <MessagePartAttribute>().Single(); return(new MessagePart(field, attribute)); }
/// <summary> /// Reflects over some <see cref="IMessage"/>-implementing type /// and prepares to serialize/deserialize instances of that type. /// </summary> internal void ReflectMessageType() { this.mapping = new Dictionary <string, MessagePart>(); Type currentType = this.messageTypeAndVersion.Type; do { foreach (MemberInfo member in currentType.GetMembers(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)) { if (member is PropertyInfo || member is FieldInfo) { MessagePartAttribute partAttribute = (from a in member.GetCustomAttributes(typeof(MessagePartAttribute), true).OfType <MessagePartAttribute>() orderby a.MinVersionValue descending where a.MinVersionValue <= this.messageTypeAndVersion.Version where a.MaxVersionValue >= this.messageTypeAndVersion.Version select a).FirstOrDefault(); if (partAttribute != null) { MessagePart part = new MessagePart(member, partAttribute); this.mapping.Add(part.Name, part); } } } currentType = currentType.BaseType; } while (currentType != null); }
private static MessagePart GetMessagePart(Type messageType, string memberName) { FieldInfo field = messageType.GetField(memberName, BindingFlags.NonPublic | BindingFlags.Instance); MessagePartAttribute attribute = field.GetCustomAttributes(typeof(MessagePartAttribute), true).OfType <MessagePartAttribute>().Single(); return(new MessagePart(field, attribute)); }
public void RequiredMinAndMaxVersions() { Type messageType = typeof(MessageWithMinAndMaxVersionParts); FieldInfo newIn2Field = messageType.GetField("NewIn2", BindingFlags.Public | BindingFlags.Instance); MessagePartAttribute newIn2Attribute = newIn2Field.GetCustomAttributes(typeof(MessagePartAttribute), true).OfType <MessagePartAttribute>().Single(); FieldInfo removedIn3Field = messageType.GetField("RemovedIn3", BindingFlags.Public | BindingFlags.Instance); MessagePartAttribute removedIn3Attribute = removedIn3Field.GetCustomAttributes(typeof(MessagePartAttribute), true).OfType <MessagePartAttribute>().Single(); Assert.AreEqual(new Version(2, 0), newIn2Attribute.MinVersionValue); Assert.AreEqual(new Version(2, 5), removedIn3Attribute.MaxVersionValue); }
internal MessagePart(MemberInfo member, MessagePartAttribute attribute) { Contract.Requires <ArgumentNullException>(member != null); Contract.Requires <ArgumentException>(member is FieldInfo || member is PropertyInfo); Contract.Requires <ArgumentNullException>(attribute != null); this.field = member as FieldInfo; this.property = member as PropertyInfo; this.Name = attribute.Name ?? member.Name; this.RequiredProtection = attribute.RequiredProtection; this.IsRequired = attribute.IsRequired; this.AllowEmpty = attribute.AllowEmpty; this.memberDeclaredType = (this.field != null) ? this.field.FieldType : this.property.PropertyType; this.defaultMemberValue = DeriveDefaultValue(this.memberDeclaredType); Contract.Assume(this.memberDeclaredType != null); // CC missing PropertyInfo.PropertyType ensures result != null if (attribute.Encoder == null) { if (!converters.TryGetValue(this.memberDeclaredType, out this.converter)) { this.converter = new ValueMapping( obj => obj != null ? obj.ToString() : null, str => str != null ? Convert.ChangeType(str, this.memberDeclaredType, CultureInfo.InvariantCulture) : null); } } else { this.converter = new ValueMapping(GetEncoder(attribute.Encoder)); } // readonly and const fields are considered legal, and "constants" for message transport. FieldAttributes constAttributes = FieldAttributes.Static | FieldAttributes.Literal | FieldAttributes.HasDefault; if (this.field != null && ( (this.field.Attributes & FieldAttributes.InitOnly) == FieldAttributes.InitOnly || (this.field.Attributes & constAttributes) == constAttributes)) { this.IsConstantValue = true; } else if (this.property != null && !this.property.CanWrite) { this.IsConstantValue = true; } // Validate a sane combination of settings this.ValidateSettings(); }
/// <summary> /// Reflects over some <see cref="IMessage"/>-implementing type /// and prepares to serialize/deserialize instances of that type. /// </summary> private void ReflectMessageType() { this.mapping = new Dictionary <string, MessagePart>(); Type currentType = this.MessageType; do { foreach (MemberInfo member in currentType.GetMembers(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)) { if (member is PropertyInfo || member is FieldInfo) { MessagePartAttribute partAttribute = (from a in member.GetCustomAttributes(typeof(MessagePartAttribute), true).OfType <MessagePartAttribute>() orderby a.MinVersionValue descending where a.MinVersionValue <= this.MessageVersion where a.MaxVersionValue >= this.MessageVersion select a).FirstOrDefault(); if (partAttribute != null) { MessagePart part = new MessagePart(member, partAttribute); if (this.mapping.ContainsKey(part.Name)) { Logger.Messaging.WarnFormat( "Message type {0} has more than one message part named {1}. Inherited members will be hidden.", this.MessageType.Name, part.Name); } else { this.mapping.Add(part.Name, part); } } } } currentType = currentType.BaseType; } while (currentType != null); BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public; this.Constructors = this.MessageType.GetConstructors(flags); }
internal MessagePart(MemberInfo member, MessagePartAttribute attribute) { Requires.NotNull(member, "member"); Requires.That(member is FieldInfo || member is PropertyInfo, "member", "Member must be a property or field."); Requires.NotNull(attribute, "attribute"); this.field = member as FieldInfo; this.property = member as PropertyInfo; this.Name = attribute.Name ?? member.Name; this.RequiredProtection = attribute.RequiredProtection; this.IsRequired = attribute.IsRequired; this.AllowEmpty = attribute.AllowEmpty; this.IsSecuritySensitive = attribute.IsSecuritySensitive; this.memberDeclaredType = (this.field != null) ? this.field.FieldType : this.property.PropertyType; this.defaultMemberValue = DeriveDefaultValue(this.memberDeclaredType); Assumes.True(this.memberDeclaredType != null); // CC missing PropertyInfo.PropertyType ensures result != null if (attribute.Encoder == null) { if (!converters.TryGetValue(this.memberDeclaredType, out this.converter)) { if (this.memberDeclaredType.GetTypeInfo().IsGenericType&& this.memberDeclaredType.GetGenericTypeDefinition() == typeof(Nullable <>)) { // It's a nullable type. Try again to look up an appropriate converter for the underlying type. Type underlyingType = Nullable.GetUnderlyingType(this.memberDeclaredType); ValueMapping underlyingMapping; if (converters.TryGetValue(underlyingType, out underlyingMapping)) { this.converter = new ValueMapping( underlyingMapping.ValueToString, null, str => str != null ? underlyingMapping.StringToValue(str) : null); } else { this.converter = GetDefaultEncoder(underlyingType); } } else { this.converter = GetDefaultEncoder(this.memberDeclaredType); } } } else { this.converter = new ValueMapping(GetEncoder(attribute.Encoder)); } // readonly and const fields are considered legal, and "constants" for message transport. FieldAttributes constAttributes = FieldAttributes.Static | FieldAttributes.Literal | FieldAttributes.HasDefault; if (this.field != null && ( (this.field.Attributes & FieldAttributes.InitOnly) == FieldAttributes.InitOnly || (this.field.Attributes & constAttributes) == constAttributes)) { this.IsConstantValue = true; this.IsConstantValueAvailableStatically = this.field.IsStatic; } else if (this.property != null && !this.property.CanWrite) { this.IsConstantValue = true; } // Validate a sane combination of settings this.ValidateSettings(); }
/// <summary> /// Initializes a new instance of the <see cref="MessagePart"/> class. /// </summary> /// <param name="member"> /// A property or field of an <see cref="IMessage"/> implementing type /// that has a <see cref="MessagePartAttribute"/> attached to it. /// </param> /// <param name="attribute"> /// The attribute discovered on <paramref name="member"/> that describes the /// serialization requirements of the message part. /// </param> internal MessagePart(MemberInfo member, MessagePartAttribute attribute) { if (member == null) { throw new ArgumentNullException("member"); } this.field = member as FieldInfo; this.property = member as PropertyInfo; if (this.field == null && this.property == null) { throw new ArgumentException( string.Format( CultureInfo.CurrentCulture, MessagingStrings.UnexpectedType, typeof(FieldInfo).Name + ", " + typeof(PropertyInfo).Name, member.GetType().Name), "member"); } if (attribute == null) { throw new ArgumentNullException("attribute"); } this.Name = attribute.Name ?? member.Name; this.RequiredProtection = attribute.RequiredProtection; this.IsRequired = attribute.IsRequired; this.AllowEmpty = attribute.AllowEmpty; this.memberDeclaredType = (this.field != null) ? this.field.FieldType : this.property.PropertyType; this.defaultMemberValue = DeriveDefaultValue(this.memberDeclaredType); if (attribute.Encoder == null) { if (!converters.TryGetValue(this.memberDeclaredType, out this.converter)) { this.converter = new ValueMapping( obj => obj != null ? obj.ToString() : null, str => str != null ? Convert.ChangeType(str, this.memberDeclaredType, CultureInfo.InvariantCulture) : null); } } else { var encoder = GetEncoder(attribute.Encoder); this.converter = new ValueMapping( obj => encoder.Encode(obj), str => encoder.Decode(str)); } // readonly and const fields are considered legal, and "constants" for message transport. FieldAttributes constAttributes = FieldAttributes.Static | FieldAttributes.Literal | FieldAttributes.HasDefault; if (this.field != null && ( (this.field.Attributes & FieldAttributes.InitOnly) == FieldAttributes.InitOnly || (this.field.Attributes & constAttributes) == constAttributes)) { this.IsConstantValue = true; } else if (this.property != null && !this.property.CanWrite) { this.IsConstantValue = true; } // Validate a sane combination of settings this.ValidateSettings(); }