static public Type GetReferenceType(IEntity entity, PropertyInfo property) { Type type = null; using (LogGroup logGroup = LogGroup.StartDebug("Retrieving the referenced entity type.")) { if (entity == null) { throw new ArgumentNullException("entity"); } if (property == null) { throw new ArgumentNullException("property"); } LogWriter.Debug("Entity type: " + entity.GetType().ToString()); LogWriter.Debug("Property name: " + property.Name); LogWriter.Debug("Property type: " + property.PropertyType.ToString()); ReferenceAttribute attribute = GetReferenceAttribute(property); type = GetReferenceType(attribute, entity, property); if (type != null) { LogWriter.Debug("Type: " + type.ToString()); } } return(type); }
static public ReferenceAttribute GetReferenceAttribute(PropertyInfo property) { if (property == null) { throw new ArgumentNullException("property"); } ReferenceAttribute attribute = null; // Logging disabled simply to reduce the size of the logs //using (LogGroup logGroup = LogGroup.Start("Retrieving the reference attribute for the specified property.", NLog.LogLevel.Debug)) //{ // LogWriter.Debug("Entity: " + sourceType.ToString()); // LogWriter.Debug("Property name: " + property.Name); // LogWriter.Debug("Property type: " + property.PropertyType.ToString()); foreach (Attribute a in property.GetCustomAttributes(true)) { if (a is ReferenceAttribute) { attribute = (ReferenceAttribute)a; } } // LogWriter.Debug("Attribute found: " + (attribute != null).ToString()); //} return(attribute); }
static public string GetMirrorPropertyNameReverse(IEntity sourceEntity, string propertyName, Type referencedEntityType) { string mirrorPropertyName = String.Empty; using (LogGroup logGroup = LogGroup.StartDebug("Retrieving mirror property name using reverse method.")) { foreach (PropertyInfo property in referencedEntityType.GetProperties()) { using (LogGroup logGroup2 = LogGroup.StartDebug("Checking property: " + property.Name)) { if (IsReference(sourceEntity.GetType(), property)) { LogWriter.Debug("Is reference == true"); Type reverseReferenceType = GetReferenceType(sourceEntity, property); LogWriter.Debug("reverseReferenceType: " + reverseReferenceType.ToString()); ReferenceAttribute attribute = GetReferenceAttribute(property); LogWriter.Debug("Mirror property name on attribute: " + attribute.MirrorPropertyName); LogWriter.Debug("Allow auto discovery (as specified by attribute): " + attribute.AutoDiscoverMirror); bool attributeMirrorPropertyMatches = attribute.MirrorPropertyName == propertyName; bool canAutoDiscover = attribute.AutoDiscoverMirror; bool typeMatches = sourceEntity.GetType().FullName.ToString() == reverseReferenceType.FullName.ToString(); LogWriter.Debug("Attribute mirror property matches: " + attributeMirrorPropertyMatches.ToString()); LogWriter.Debug("Can auto discover: " + canAutoDiscover); LogWriter.Debug("Type matches: " + typeMatches.ToString()); LogWriter.Debug("Equation: " + typeMatches.ToString() + " && (" + canAutoDiscover + " || " + attributeMirrorPropertyMatches + ")"); if (typeMatches && (canAutoDiscover || attributeMirrorPropertyMatches)) { LogWriter.Debug("Mirror property name decided: " + property.Name); mirrorPropertyName = property.Name; } } } } LogWriter.Debug("Mirror property name: " + mirrorPropertyName); } return(mirrorPropertyName); }
static public ReferenceAttribute GetReferenceAttribute(IEntity entity, string propertyName) { ReferenceAttribute attribute = null; PropertyInfo property = entity.GetType().GetProperty(propertyName); if (property == null) { throw new ArgumentException("Can't find '" + propertyName + "' property on '" + entity.GetType().FullName + "' entity type."); } attribute = GetReferenceAttribute(property); return(attribute); }
static public ReferenceAttribute GetReferenceAttribute(IEntity entity, string propertyName, Type returnType) { ReferenceAttribute attribute = null; // Logging disabled simply to reduce the size of the logs //using (LogGroup logGroup = LogGroup.Start("...", NLog.LogLevel.Debug)) //{ PropertyInfo property = entity.GetType().GetProperty(propertyName, returnType); // LogWriter.Debug("Entity: " + entity.GetType().ToString()); // LogWriter.Debug("Property name: " + propertyName); attribute = GetReferenceAttribute(property); // LogWriter.Debug("Is reference? " + isReference.ToString()); //} return(attribute); }
public static Type GetReferenceType(ReferenceAttribute attribute, IEntity sourceEntity, PropertyInfo property) { Type type = null; Type sourceType = sourceEntity.GetType(); if (attribute == null) throw new Exception("The reference attribute was not found on the '" + property.Name + "' property of the type '" + sourceType.ToString() + "'."); if (IsReference(sourceType, property)) { if (attribute.TypeName != null && attribute.TypeName != String.Empty) { LogWriter.Debug("attribute.TypeName != String.Empty"); LogWriter.Debug("attribute.TypeName == " + attribute.TypeName); type = EntityState.GetType(attribute.TypeName); } else if (attribute.TypePropertyName != String.Empty) { PropertyInfo typeProperty = sourceType.GetProperty(attribute.TypePropertyName); // TODO: Use a custom exception instead of a general one if (typeProperty == null) throw new Exception("'" + attribute.TypePropertyName + "' property not found on '" + sourceType.Name + "' type as specified by reference attribute on '" + property.Name + "' property."); string typeName = (string)typeProperty.GetValue(sourceEntity, null); // If a type name is specified then get the type otherwise leave it null if (typeName != null && typeName != String.Empty) { type = EntityState.GetType(typeName); } } else { LogWriter.Debug("attribute.TypeName == String.Empty"); // If the property is a single entity instance if (IsSingleReference(sourceType, property)) { LogWriter.Debug("Is a single entity"); type = property.PropertyType; } // Otherwise the property is a collection/array else { LogWriter.Debug("Is a collection/array"); // If it's an array this should work type = property.PropertyType.GetElementType(); // If it's not an array (ie. it's a collection) then this should work if (type == null) type = property.PropertyType.GetGenericArguments()[0]; } } } return type; }
static public string GetMirrorPropertyName(IEntity sourceEntity, PropertyInfo property) { string mirrorPropertyName = String.Empty; using (LogGroup logGroup = LogGroup.StartDebug("Retrieving the name of the mirror property that corresponds with the specified property.")) { if (sourceEntity == null) { throw new ArgumentNullException("sourceEntity"); } if (property == null) { throw new ArgumentNullException("property"); } Type sourceType = sourceEntity.GetType(); ReferenceAttribute attribute = GetReferenceAttribute(property); if (attribute == null) { throw new Exception("No ReferenceAttribute found on the '" + property.Name + "' property of the type '" + sourceType.ToString() + "'."); } Type referencedEntityType = GetReferenceType(sourceEntity, property); // Is the mirror property name specified on the attribute? if (attribute.MirrorPropertyName != String.Empty || attribute.MirrorPropertyName != null) { mirrorPropertyName = attribute.MirrorPropertyName; } else { // Should the mirror property name be automatically discovered based on the property type matching the source entity? if (attribute.AutoDiscoverMirror) { // Loop through each property and check the types foreach (PropertyInfo p in referencedEntityType.GetProperties()) { // Is the property a reference? if (IsReference(referencedEntityType, p)) { IEntity[] referencedEntities = GetReferencedEntities(sourceEntity, property); // Retrieve the entity type being stored on the property Type reciprocalType = GetReferenceType(referencedEntities[0], p); // If the entity types match then return the property name if (reciprocalType.FullName == sourceType.FullName) { mirrorPropertyName = p.Name; } } } } } LogWriter.Debug("Mirror property name: " + mirrorPropertyName); } return(mirrorPropertyName); }
static public bool IsReference(Type sourceType, PropertyInfo property) { bool isReference = false; bool validType = false; if (property == null) { throw new ArgumentNullException("property"); } if (sourceType == null) { throw new ArgumentNullException("sourceType"); } //using (LogGroup logGroup = LogGroup.Start("Checking if the specified property is an entity reference.", NLog.LogLevel.Debug)) //{ // LogWriter.Debug("Entity: " + sourceType.ToString()); // LogWriter.Debug("Property name: " + property.Name); ReferenceAttribute reference = GetReferenceAttribute(property); isReference = reference != null; if (isReference) { Type referenceType = property.PropertyType; if (typeof(Array).IsAssignableFrom(referenceType)) { // If it's an array this should work referenceType = property.PropertyType.GetElementType(); // If it's not an array (ie. it's a collection) then this should work if (referenceType == null) { //LogWriter.Debug("Property is a collection."); referenceType = property.PropertyType.GetGenericArguments()[0]; } //else // LogWriter.Debug("Property is an array."); } validType = EntityState.IsType(referenceType); // If it's not a valid type then try using the type sepcified on the attribute if (!validType && reference.TypeName != String.Empty) { referenceType = EntityState.GetType(reference.TypeName); validType = EntityState.IsType(referenceType); } if (!validType) { throw new Exception("Referenced type '" + referenceType.Name + "' on property '" + property.Name + "' of source entity type '" + sourceType.FullName + "' is not registered as a valid entity type. Make sure that the referenced type has an EntityAttribute."); } } // LogWriter.Debug("Is reference? " + isReference.ToString()); // LogWriter.Debug("Valid type? " + validType.ToString()); //} return(isReference && validType); }
static public Type GetReferenceType(ReferenceAttribute attribute, IEntity sourceEntity, PropertyInfo property) { Type type = null; Type sourceType = sourceEntity.GetType(); if (attribute == null) { throw new Exception("The reference attribute was not found on the '" + property.Name + "' property of the type '" + sourceType.ToString() + "'."); } if (IsReference(sourceType, property)) { if (attribute.TypeName != null && attribute.TypeName != String.Empty) { LogWriter.Debug("attribute.TypeName != String.Empty"); LogWriter.Debug("attribute.TypeName == " + attribute.TypeName); type = EntityState.GetType(attribute.TypeName); } else if (attribute.TypePropertyName != String.Empty) { PropertyInfo typeProperty = sourceType.GetProperty(attribute.TypePropertyName); // TODO: Use a custom exception instead of a general one if (typeProperty == null) { throw new Exception("'" + attribute.TypePropertyName + "' property not found on '" + sourceType.Name + "' type as specified by reference attribute on '" + property.Name + "' property."); } string typeName = (string)typeProperty.GetValue(sourceEntity, null); // If a type name is specified then get the type otherwise leave it null if (typeName != null && typeName != String.Empty) { type = EntityState.GetType(typeName); } } else { LogWriter.Debug("attribute.TypeName == String.Empty"); // If the property is a single entity instance if (IsSingleReference(sourceType, property)) { LogWriter.Debug("Is a single entity"); type = property.PropertyType; } // Otherwise the property is a collection/array else { LogWriter.Debug("Is a collection/array"); // If it's an array this should work type = property.PropertyType.GetElementType(); // If it's not an array (ie. it's a collection) then this should work if (type == null) { type = property.PropertyType.GetGenericArguments()[0]; } } } } return(type); }