/// <summary> /// Uses the <see cref="T:PropertyInfo" /> setter to set the value of of the context object's member data. /// </summary> /// <param name="pi">The field to set the value in.</param> /// <param name="value">The value that will be set.</param> /// <exception cref="T:Ikarii.Lib.Data.Alpaca.MappingException">This exception is thrown if /// <see cref="T:System.Runtime.Serialization.FormatterConverter"/> is unable to set /// <paramref name="pi"/> with <paramref name="value"/>.</exception> internal void SetMappedValue( PropertyInfo pi, object value ) { if( value != null ) { try { if( value.GetType() == pi.PropertyType || value.GetType().BaseType == pi.PropertyType ) { pi.SetValue( this.Instance, value, null ); } else if( pi.PropertyType == typeof( System.Guid ) ) { pi.SetValue( this.Instance, new Guid( value.ToString() ), null ); } else if( pi.PropertyType.IsGenericType && ( pi.PropertyType.GetGenericTypeDefinition().Equals( typeof( Nullable<> ) ) || pi.PropertyType.GetGenericTypeDefinition().Equals( typeof( Trackable<> ) ) ) ) { Type generic = pi.PropertyType.GetGenericArguments()[ 0 ]; pi.SetValue( this.Instance, Convert.ChangeType( value, generic ), null ); } else if( Utility.ImplementsInterface( pi.PropertyType, typeof( System.Collections.ICollection ) ) ) { pi.SetValue( this.Instance, value, null ); } else { try { FormatterConverter fc = new FormatterConverter(); Type valuetype = pi.PropertyType; object v = fc.Convert( value, valuetype ); pi.SetValue( this.Instance, v, null ); } catch( Exception e ) { throw new MappingException( String.Format( System.Globalization.CultureInfo.InvariantCulture, @"There was difficulty setting the field named {0} in {1}. The field's return type is {2} and the value's type was {3}. {2} cannot be converted to {3}. ", pi.Name, pi.DeclaringType, pi.PropertyType, value.GetType() ), e ); } } } catch( Exception e ) { throw new MappingException( String.Format( System.Globalization.CultureInfo.InvariantCulture, @"Unable to set member {0} with value {1} in {2}.", pi.Name, value.ToString(), pi.DeclaringType.Name ), e ); } } }
/// <summary> /// Creates an object instance based on the specified object definition. /// </summary> /// <param name="objectDefinition">The definition of the object to create.</param> /// <returns>An instance based on the specified object definition.</returns> private static object GetObject(ObjectDefinition objectDefinition) { object instance = null; FormatterConverter formatterConverter = new FormatterConverter(); if (objectDefinition.ConstructorParameters.Count > 0) { ConstructorInfo[] constructors = objectDefinition.Type.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); foreach (ConstructorInfo constructorInfo in constructors) { ParameterInfo[] constructorParameters = constructorInfo.GetParameters(); if (constructorParameters.Length == objectDefinition.ConstructorParameters.Count) { bool match = true; for (int i = 0; i < constructorParameters.Length; i++) { if (objectDefinition.ConstructorParameters[i] is ObjectDefinition) { ObjectDefinition constructorParameterDefinition = (ObjectDefinition) objectDefinition.ConstructorParameters[i]; if (constructorParameters[i].ParameterType != constructorParameterDefinition.Type) { match = false; break; } } else if (constructorParameters[i].ParameterType != objectDefinition.ConstructorParameters[i].GetType()) { match = false; break; } } if (match) { List<object> parameters = new List<object>(); for (int i = 0; i < objectDefinition.ConstructorParameters.Count; i++) { object parameter = objectDefinition.ConstructorParameters[i]; if (parameter is ObjectDefinition) { ObjectDefinition parameterDefinition = (ObjectDefinition) parameter; parameters.Add(GetObject(parameterDefinition)); } else { parameter = formatterConverter.Convert(parameter, constructorParameters[i].ParameterType); parameters.Add(parameter); } } instance = constructorInfo.Invoke(parameters.ToArray()); break; } } } } else { instance = Activator.CreateInstance(objectDefinition.Type); } if (instance == null) { throw new ArgumentException("A match could not be found for the specified ObjectDefinition [" + objectDefinition.Id + "]. Please verify the class definition and the configured constructor information."); } else { if (objectDefinition.Properties.Count > 0) { foreach (PropertyInfo propertyInfo in objectDefinition.Type.GetProperties()) { object propertyValue = objectDefinition.Properties[propertyInfo.Name]; if (propertyValue != null) { if (propertyValue is ObjectDefinition) { propertyValue = GetObject(propertyValue as ObjectDefinition); } propertyInfo.SetValue(instance, formatterConverter.Convert(propertyValue, propertyInfo.PropertyType), null); } } } return instance; } }