/// <summary> /// Initializes a new <see cref="AbstractTypeResolver"/> /// </summary> /// <param name="abstractType">The abstract type to resolve the implementation type for</param> public AbstractTypeResolver(Type abstractType) { DiscriminatorAttribute discriminatorAttribute = abstractType.GetCustomAttribute <DiscriminatorAttribute>(); if (discriminatorAttribute == null) { throw new NullReferenceException($"Failed to find the required '{nameof(DiscriminatorAttribute)}'"); } this.DiscriminatorProperty = abstractType.GetProperty(discriminatorAttribute.Property, BindingFlags.Default | BindingFlags.Public | BindingFlags.Instance); if (this.DiscriminatorProperty == null) { throw new NullReferenceException($"Failed to find the specified discriminator property '{discriminatorAttribute.Property}' in type '{abstractType.Name}'"); } this.TypeMappings = new Dictionary <string, Type>(); foreach (Type derivedType in typeof(StateType).Assembly.GetTypes() .Where(t => t.IsClass && !t.IsAbstract && t.BaseType == abstractType)) { DiscriminatorValueAttribute discriminatorValueAttribute = derivedType.GetCustomAttribute <DiscriminatorValueAttribute>(); if (discriminatorValueAttribute == null) { continue; } string discriminatorValue = null; if (discriminatorValueAttribute.Value.GetType().IsEnum) { discriminatorValue = EnumHelper.Stringify(discriminatorValueAttribute.Value, this.DiscriminatorProperty.PropertyType); } else { discriminatorValue = discriminatorValueAttribute.Value.ToString(); } this.TypeMappings.Add(discriminatorValue.ToLower(), derivedType); } }
public DiscriminatorModelBinder( IModelBinderFactory factory, IModelMetadataProvider metadataProvider, DiscriminatorAttribute discriminator, IList <DiscriminatorCaseAttribute> cases, IDiscriminatorReader reader ) { _factory = factory; _metadataProvider = metadataProvider; _discriminator = discriminator; _cases = cases; _reader = reader; }
/// <summary> Write a Discriminator XML Element from attributes in a member. </summary> public virtual void WriteDiscriminator(System.Xml.XmlWriter writer, System.Reflection.MemberInfo member, DiscriminatorAttribute attribute, BaseAttribute parentAttribute, System.Type mappedClass) { writer.WriteStartElement( "discriminator" ); // Attribute: <column> if(attribute.Column != null) writer.WriteAttributeString("column", GetAttributeValue(attribute.Column, mappedClass)); // Attribute: <formula> if(attribute.Formula != null) writer.WriteAttributeString("formula", GetAttributeValue(attribute.Formula, mappedClass)); // Attribute: <type> if(attribute.Type != null) writer.WriteAttributeString("type", GetAttributeValue(attribute.Type, mappedClass)); // Attribute: <not-null> if( attribute.NotNullSpecified ) writer.WriteAttributeString("not-null", attribute.NotNull ? "true" : "false"); // Attribute: <length> if(attribute.Length != -1) writer.WriteAttributeString("length", attribute.Length.ToString()); // Attribute: <force> if( attribute.ForceSpecified ) writer.WriteAttributeString("force", attribute.Force ? "true" : "false"); // Attribute: <insert> if( attribute.InsertSpecified ) writer.WriteAttributeString("insert", attribute.Insert ? "true" : "false"); WriteUserDefinedContent(writer, member, null, attribute); System.Collections.ArrayList memberAttribs = GetSortedAttributes(member); int attribPos; // Find the position of the DiscriminatorAttribute (its <sub-element>s must be after it) for(attribPos=0; attribPos<memberAttribs.Count; attribPos++) if( memberAttribs[attribPos] is DiscriminatorAttribute && ((BaseAttribute)memberAttribs[attribPos]).Position == attribute.Position ) break; // found int i = attribPos + 1; // Element: <column> for(; i<memberAttribs.Count; i++) { BaseAttribute memberAttrib = memberAttribs[i] as BaseAttribute; if( IsNextElement(memberAttrib, parentAttribute, attribute.GetType()) || IsNextElement(memberAttrib, attribute, typeof(ColumnAttribute)) ) break; // next attributes are 'elements' of the same level OR for 'sub-elements' else { if( memberAttrib is DiscriminatorAttribute ) break; // Following attributes are for this Discriminator if( memberAttrib is ColumnAttribute ) WriteColumn(writer, member, memberAttrib as ColumnAttribute, attribute, mappedClass); } } WriteUserDefinedContent(writer, member, typeof(ColumnAttribute), attribute); // Element: <formula> for(; i<memberAttribs.Count; i++) { BaseAttribute memberAttrib = memberAttribs[i] as BaseAttribute; if( IsNextElement(memberAttrib, parentAttribute, attribute.GetType()) || IsNextElement(memberAttrib, attribute, typeof(FormulaAttribute)) ) break; // next attributes are 'elements' of the same level OR for 'sub-elements' else { if( memberAttrib is DiscriminatorAttribute ) break; // Following attributes are for this Discriminator if( memberAttrib is FormulaAttribute ) WriteFormula(writer, member, memberAttrib as FormulaAttribute, attribute, mappedClass); } } WriteUserDefinedContent(writer, member, typeof(FormulaAttribute), attribute); writer.WriteEndElement(); }