private void AddProperty(IPropertyBuildContext <TSubject> context, MethodInfo buildChildContextMethod, PropertyInfo d) { PropertyInfo descriptor = d; Type propertyType = descriptor.PropertyType; AssignmentPolicyAttribute assignmentPolicyAttribute = descriptor.GetAttribute <AssignmentPolicyAttribute>(); NullableAttribute nullableAttribute = descriptor.GetAttribute <NullableAttribute>(); bool nullable = nullableAttribute == null || nullableAttribute.IsNullable; AssignmentPolicy policy; if (assignmentPolicyAttribute != null && context.Policy == AssignmentPolicy.Default) { policy = assignmentPolicyAttribute.Policy; } else { policy = context.Policy == AssignmentPolicy.Default ? AssignmentPolicy.CreateNewInstance : context.Policy; } object childbuilder; object currentPropertyValue = descriptor.GetValue(context.CurrentInstance, null); if (currentPropertyValue == null && nullable) { //todo: make this dependent on yet-to-implement nullable attribute childbuilder = context.GetPropertyMapBuilder(propertyType, currentPropertyValue); } else { childbuilder = context.GetPropertyMapBuilder(currentPropertyValue); } string name = descriptor.GetDisplayName(); if (childbuilder != null) { // Create the SetInstanceDelegate that uses the builders' CurrentInstance for the set operation Delegate setMemberInstanceDelegate; { Type helperSetInstanceDelegateType = typeof(HelperSetInstanceDelegate <,>) .MakeGenericType(propertyType, typeof(TSubject)); ConstructorInfo setterConstructorInfo = helperSetInstanceDelegateType .GetConstructor(new[] { typeof(PropertyInfo), typeof(IPropertyBuildContext <TSubject>) }); object helperSetInstanceDelegateInstance = setterConstructorInfo .Invoke(new object[] { descriptor, context }); MethodInfo method = helperSetInstanceDelegateType.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance)[0]; setMemberInstanceDelegate = Delegate.CreateDelegate(typeof(SetInstanceDelegate <>).MakeGenericType(propertyType), helperSetInstanceDelegateInstance, method); } // Create the SetInstanceDelegate that uses the builders' CurrentInstance for the set operation Delegate getMemberInstanceDelegate; { Type helperInstanceDelegateType = typeof(HelperGetInstanceDelegate <,>) .MakeGenericType(propertyType, typeof(TSubject)); ConstructorInfo getterConstructorInfo = helperInstanceDelegateType .GetConstructor(new[] { typeof(PropertyInfo), typeof(IPropertyBuildContext <TSubject>) }); object helperGetInstanceDelegateInstance = getterConstructorInfo .Invoke(new object[] { descriptor, context }); MethodInfo method = helperInstanceDelegateType.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance)[0]; getMemberInstanceDelegate = Delegate.CreateDelegate(typeof(GetInstanceDelegate <>).MakeGenericType(propertyType), helperGetInstanceDelegateInstance, method); } object childContext = buildChildContextMethod.MakeGenericMethod(propertyType).Invoke(context, new object[] { name, getMemberInstanceDelegate , setMemberInstanceDelegate , policy }); MethodInfo buildPropertyMapMethod = typeof(IPropertyMapBuilder).GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance)[0]; buildPropertyMapMethod.MakeGenericMethod(propertyType).Invoke(childbuilder, new[] { childContext }); } else { context.AddEntry(name, new ReflectionGetter <TSubject>(descriptor, context), new ReflectionSetter <TSubject>(descriptor, context)); } }
protected override void BuildPropertyMapImpl(IPropertyBuildContext <TSubject> builder) { MethodInfo[] infos = typeof(IPropertyBuildContext <>).MakeGenericType(typeof(TSubject)).GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public); MethodInfo buildChildContextMethod = null; foreach (MethodInfo info in infos) { if (info.IsGenericMethod && info.ReturnType.IsGenericType) { buildChildContextMethod = info; break; } } if (buildChildContextMethod == null) { throw new InvalidDataException("Method not found!"); } TSubject instance = builder.CurrentInstance; PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(instance); foreach (PropertyDescriptor d in properties) { PropertyDescriptor descriptor = d; AttributeBuilderAttribute mapAttribute = (AttributeBuilderAttribute)descriptor.Attributes[typeof(AttributeBuilderAttribute)]; if (mapAttribute != null && mapAttribute.Invisible) { continue; } DisplayNameAttribute displayNameAttribute = (DisplayNameAttribute)descriptor.Attributes[typeof(DisplayNameAttribute)]; string propertyName; if (displayNameAttribute == null || displayNameAttribute.DisplayName.Length < 1) { propertyName = descriptor.Name; } else { propertyName = displayNameAttribute.DisplayName; } AssignmentPolicyAttribute assignmentPolicyAttribute = (AssignmentPolicyAttribute)descriptor.Attributes[typeof(AssignmentPolicyAttribute)]; Type propertyType = descriptor.PropertyType; NullableAttribute nullableAttribute = (NullableAttribute)descriptor.Attributes[typeof(NullableAttribute)]; bool nullable = nullableAttribute == null || nullableAttribute.IsNullable; AssignmentPolicy policy; if (assignmentPolicyAttribute != null && builder.Policy == AssignmentPolicy.Default) { policy = assignmentPolicyAttribute.Policy; } else { policy = builder.Policy == AssignmentPolicy.Default ? AssignmentPolicy.ModifyInstance : builder.Policy; } object childbuilder; object currentPropertyValue = descriptor.GetValue(builder.CurrentInstance); if (currentPropertyValue == null && nullable) { //todo: make this dependent on yet-to-implement nullable attribute childbuilder = builder.GetPropertyMapBuilder(propertyType, currentPropertyValue); } else { childbuilder = builder.GetPropertyMapBuilder(currentPropertyValue); } if (childbuilder != null) { // Create the SetInstanceDelegate that uses the builders' CurrentInstance for the set operation Delegate setMemberInstanceDelegate; { Type helperSetInstanceDelegateType = typeof(HelperSetInstanceDelegate <,>) .MakeGenericType(propertyType, typeof(TSubject)); ConstructorInfo setterConstructorInfo = helperSetInstanceDelegateType .GetConstructor(new Type[] { typeof(PropertyDescriptor), typeof(IPropertyBuildContext <TSubject>) }); object helperSetInstanceDelegateInstance = setterConstructorInfo .Invoke(new object[] { descriptor, builder }); MethodInfo method = helperSetInstanceDelegateType.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance)[0]; setMemberInstanceDelegate = Delegate.CreateDelegate(typeof(SetInstanceDelegate <>).MakeGenericType(propertyType), helperSetInstanceDelegateInstance, method); } // Create the SetInstanceDelegate that uses the builders' CurrentInstance for the set operation Delegate getMemberInstanceDelegate; { Type helperInstanceDelegateType = typeof(HelperGetInstanceDelegate <,>) .MakeGenericType(propertyType, typeof(TSubject)); ConstructorInfo getterConstructorInfo = helperInstanceDelegateType .GetConstructor(new Type[] { typeof(PropertyDescriptor), typeof(IPropertyBuildContext <TSubject>) }); object helperGetInstanceDelegateInstance = getterConstructorInfo .Invoke(new object[] { descriptor, builder }); MethodInfo method = helperInstanceDelegateType.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance)[0]; getMemberInstanceDelegate = Delegate.CreateDelegate(typeof(GetInstanceDelegate <>).MakeGenericType(propertyType), helperGetInstanceDelegateInstance, method); } object childContext = buildChildContextMethod.MakeGenericMethod(propertyType).Invoke(builder, new object[] { propertyName, getMemberInstanceDelegate, setMemberInstanceDelegate, policy }); MethodInfo buildPropertyMapMethod = typeof(IPropertyMapBuilder).GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance)[0]; buildPropertyMapMethod.MakeGenericMethod(propertyType).Invoke(childbuilder, new object[] { childContext }); } else { builder.AddEntry(propertyName, new ReflectionGetter <TSubject>(descriptor, builder), new ReflectionSetter <TSubject>(descriptor, builder)); } } }