Пример #1
0
        /// <summary>
        /// Configures additional attributes for an option item or option group, such as collapsed state and group visibility.
        /// </summary>
        /// <param name="item">The item or group to configure.</param>
        /// <param name="propertyInfo">The associated property info.</param>
        protected virtual void ConfigureItem(IOptionItem item, PropertyInfo propertyInfo)
        {
            NullableAttribute nullableAttribute =
                (NullableAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(NullableAttribute));

            if (nullableAttribute != null)
            {
                item.Attributes[OptionItem.SupportNullValueAttribute] = nullableAttribute.IsNullable;
            }
            else
            {
                CanBeNullAttribute canBeNull =
                    (CanBeNullAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(CanBeNullAttribute));
                NotNullAttribute notNull =
                    (NotNullAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(NotNullAttribute));
                if (canBeNull != null)
                {
                    item.Attributes[OptionItem.SupportNullValueAttribute] = true;
                }
                else if (notNull != null)
                {
                    item.Attributes[OptionItem.SupportNullValueAttribute] = false;
                }
            }

            DescriptionAttribute attribute = GetAttribute <DescriptionAttribute>(propertyInfo);

            if (attribute != null && !attribute.IsDefaultAttribute())
            {
                item.Attributes[OptionItem.DescriptionAttribute] = attribute.Description;
            }

            var customAttributes = Attribute.GetCustomAttributes(propertyInfo);

            foreach (var attrib in customAttributes.OfType <OptionItemAttributeAttribute>())
            {
                item.Attributes[attrib.Name] = attrib.Value;
            }
        }
        /// <summary>
        /// Configures additional attributes for an option item or option group, such as collapsed state and group visibility.
        /// </summary>
        /// <param name="item">The item or group to configure.</param>
        /// <param name="propertyInfo">The associated property info.</param>
        protected virtual void ConfigureItem(IOptionItem item, PropertyInfo propertyInfo)
        {
            TableEditorFactory.RenderingHints   tableRenderingHints   = TableEditorFactory.RenderingHints.Collapsed;
            DefaultEditorFactory.RenderingHints defaultRenderingHints = DefaultEditorFactory.RenderingHints.Invisible;
            ItemRenderingHintsAttribute         hintsAttribute        =
                (ItemRenderingHintsAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(ItemRenderingHintsAttribute));

            if (hintsAttribute != null)
            {
                tableRenderingHints   = hintsAttribute.TableRenderingHints;
                defaultRenderingHints = hintsAttribute.DialogRenderingHints;
            }
            item.SetAttribute(TableEditorFactory.RENDERING_HINTS_ATTRIBUTE, tableRenderingHints);
            item.SetAttribute(DefaultEditorFactory.RENDERING_HINTS_ATTRIBUTE, defaultRenderingHints);

            NullableAttribute nullableAttribute =
                (NullableAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(NullableAttribute));

            if (nullableAttribute != null)
            {
                item.SetAttribute(OptionItem.SUPPORT_NULL_VALUE_ATTRIBUTE, nullableAttribute.IsNullable);
            }

            DescriptionAttribute attribute = GetAttribute <DescriptionAttribute>(propertyInfo);

            if (attribute != null && !attribute.IsDefaultAttribute())
            {
                item.SetAttribute(OptionItem.DESCRIPTION_ATTRIBUTE, attribute.Description);
            }

            var customAttributes = Attribute.GetCustomAttributes(propertyInfo);

            foreach (var attrib in customAttributes.OfType <OptionItemAttributeAttribute>())
            {
                item.SetAttribute(attrib.Name, attrib.Value);
            }
        }
        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));
                }
            }
        }