Exemple #1
0
        public override AttributeDeclaration GetAttributeDeclaration(Attribute attribute)
        {
            CustomValidationAttribute cva = (CustomValidationAttribute)attribute;

            // Our convention is that parameter validation in the CVA occurs when it is
            // first used.  Simply ask the attribute to produce an error message, as this
            // will trigger an InvalidOperationException if the attribute is ill-formed
            cva.FormatErrorMessage(string.Empty);

            // Delegate to the base implementation to generate the attribute.
            // Note that the base implementation already checks that Types are
            // shared so we do not perform that check here.
            AttributeDeclaration attributeDeclaration = base.GetAttributeDeclaration(attribute);

            attributeDeclaration.RequiredTypes.Add(cva.ValidatorType);
            attributeDeclaration.RequiredMethods.Add(cva.ValidatorType.GetMethod(cva.Method));

            return(attributeDeclaration);
        }
Exemple #2
0
        public override AttributeDeclaration GetAttributeDeclaration(Attribute attribute)
        {
            RangeAttribute       rangeAttribute       = (RangeAttribute)attribute;
            AttributeDeclaration attributeDeclaration = new AttributeDeclaration(typeof(RangeAttribute));

            // Register required resources for this ValidationAttribute
            RegisterSharedResources(rangeAttribute, attributeDeclaration);

            bool declareOperandType =
                rangeAttribute.Minimum == null ||
                rangeAttribute.Minimum.GetType() == typeof(string);

            // OperandType
            if (declareOperandType)
            {
                attributeDeclaration.ConstructorArguments.Add(rangeAttribute.OperandType);
            }

            // Minimum
            attributeDeclaration.ConstructorArguments.Add(rangeAttribute.Minimum);
            // Maximum
            attributeDeclaration.ConstructorArguments.Add(rangeAttribute.Maximum);

            // ErrorMessage
            if (rangeAttribute.ErrorMessage != null)
            {
                attributeDeclaration.NamedParameters.Add("ErrorMessage", rangeAttribute.ErrorMessage);
            }

            // ErrorMessageResourceType
            if (rangeAttribute.ErrorMessageResourceType != null)
            {
                attributeDeclaration.NamedParameters.Add("ErrorMessageResourceType", rangeAttribute.ErrorMessageResourceType);
            }

            // ErrorMessageResourceName
            if (rangeAttribute.ErrorMessageResourceName != null)
            {
                attributeDeclaration.NamedParameters.Add("ErrorMessageResourceName", rangeAttribute.ErrorMessageResourceName);
            }

            return(attributeDeclaration);
        }
        /// <summary>
        /// Generates a <see cref="AttributeDeclaration"/> representation of an
        /// <see cref="EditableAttribute"/> instance.
        /// </summary>
        /// <param name="attribute">The <see cref="EditableAttribute"/>.</param>
        /// <returns>A <see cref="AttributeDeclaration"/> representation of
        /// <paramref name="attribute"/>.</returns>
        /// <exception cref="InvalidCastException">if <paramref name="attribute"/> is
        /// not a <see cref="EditableAttribute"/>.</exception>
        public override AttributeDeclaration GetAttributeDeclaration(Attribute attribute)
        {
            EditableAttribute    editableAttribute    = (EditableAttribute)attribute;
            AttributeDeclaration attributeDeclaration = new AttributeDeclaration(typeof(EditableAttribute));

            bool allowEdit         = editableAttribute.AllowEdit;
            bool allowInitialValue = editableAttribute.AllowInitialValue;

            // [EditableAttribute( {true|false} )]
            attributeDeclaration.ConstructorArguments.Add(allowEdit);

            // Only add the 'AllowInitialValue' parameter if its value does not match with
            // the 'AllowEdit' value.  See the documentation of EditableAttribute for more info.
            if (allowEdit != allowInitialValue)
            {
                // [EditableAttribute( {true|false}, AllowInitialValue = {true|false} )]
                attributeDeclaration.NamedParameters.Add("AllowInitialValue", allowInitialValue);
            }

            return(attributeDeclaration);
        }
Exemple #4
0
        public override AttributeDeclaration GetAttributeDeclaration(Attribute attribute)
        {
            var uiHintAttribute = (UIHintAttribute)attribute;

            // We override this build method only to deal with the control parameters
            // which cannot be generated by the standard builder.  If there are no
            // control parameters, let the standard builder do the work.

            IDictionary <string, object> controlParams = null;

            try
            {
                controlParams = uiHintAttribute.ControlParameters;
            }
            catch (InvalidOperationException e)
            {
                throw new AttributeBuilderException(e, typeof(UIHintAttribute), "ControlParameters");
            }

            if (controlParams == null || controlParams.Count == 0)
            {
                return(base.GetAttributeDeclaration(attribute));
            }

            var attributeDeclaration = new AttributeDeclaration(typeof(UIHintAttribute));

            // UIHint[("uiHint", "presentationLayer")]
            attributeDeclaration.ConstructorArguments.Add(uiHintAttribute.UIHint);
            attributeDeclaration.ConstructorArguments.Add(uiHintAttribute.PresentationLayer);

            // UIHint[("uiHint", "presentationLayer", ...)] -- fill in all the optional params from control parameters
            foreach (var item in controlParams)
            {
                attributeDeclaration.ConstructorArguments.Add(item.Key);
                attributeDeclaration.ConstructorArguments.Add(item.Value);
            }

            return(attributeDeclaration);
        }
        /// <summary>
        /// Returns a representative <see cref="AttributeDeclaration"/> for a given <see cref="Attribute"/> instance.
        /// </summary>
        /// <param name="attribute">An attribute instance to create a <see cref="AttributeDeclaration"/> for.</param>
        /// <returns>A <see cref="AttributeDeclaration"/> representing the <paramref name="attribute"/>.</returns>
        public virtual AttributeDeclaration GetAttributeDeclaration(Attribute attribute)
        {
            if (attribute == null)
            {
                throw new ArgumentNullException("attribute");
            }

            Type attributeType = attribute.GetType();
            AttributeDeclaration attributeDeclaration = new AttributeDeclaration(attributeType);

            // Strategy is as follows:
            //  - Fetch all the public property values from the current attribute
            //  - Determine the default value for all of these properties
            //  - From these 2 lists, determine the set of "non-default" properties.  These are what we must code gen.
            //  - From this list, determine which of these can be set only through a ctor
            //  - From the list of ctor properties and values, find the best ctor pattern for it and code gen that
            //  - For all remaining non-default properties, code gen named argument setters
            List <PropertyMap>          propertyMaps         = this.BuildPropertyMaps(attribute);
            Dictionary <string, object> currentValues        = GetPropertyValues(propertyMaps, attribute);
            Dictionary <string, object> defaultValues        = GetDefaultPropertyValues(propertyMaps, attribute, currentValues);
            List <PropertyMap>          nonDefaultProperties = GetNonDefaultProperties(propertyMaps, currentValues, defaultValues);
            List <PropertyMap>          unsettableProperties = GetUnsettableProperties(nonDefaultProperties);

            // "Unsettable" properties are all those that can be set only through a ctor (they have no public setter).
            // Go find the best ctor pattern for them and code gen that much
            ParameterInfo[] ctorParameters = FindBestConstructor(unsettableProperties, currentValues, attributeType);
            if (ctorParameters == null)
            {
                // Return null, indicating we cannot build this attribute.
                return(null);
            }

            // We found a ctor that will accept all our properties that need to be set.
            // Generate ctor arguments to match this signature.
            // Note: the ctor pattern obviously may require other arguments that are also settable,
            // so if we pass a value to the ctor, we omit it from the set of named parameters below
            foreach (ParameterInfo parameter in ctorParameters)
            {
                PropertyMap matchedPropertyMap = null;
                foreach (PropertyMap map in propertyMaps)
                {
                    PropertyInfo propertyInfo = map.Setter;
                    if (propertyInfo.Name.Equals(parameter.Name, StringComparison.OrdinalIgnoreCase) && CanValueBeAssignedToType(parameter.ParameterType, currentValues[propertyInfo.Name]))
                    {
                        matchedPropertyMap = map;
                        break;
                    }
                }
                object value = matchedPropertyMap != null ? currentValues[matchedPropertyMap.Getter.Name] : DefaultInstanceForType(parameter.ParameterType);
                attributeDeclaration.ConstructorArguments.Add(value);

                // Remove this from our list of properties we need to set so the code below skips it
                if (matchedPropertyMap != null)
                {
                    nonDefaultProperties.Remove(matchedPropertyMap);
                }
            }

            // For all remaining non-default properties, generate a named argument setter.
            // We sort these so the named parameters appear in a predictable order in generated code -- primarily for unit testing
            nonDefaultProperties.Sort(new Comparison <PropertyMap>((x, y) => string.Compare(x.Setter.Name, y.Setter.Name, StringComparison.Ordinal)));

            foreach (PropertyMap map in nonDefaultProperties)
            {
                attributeDeclaration.NamedParameters.Add(map.Setter.Name, currentValues[map.Getter.Name]);
            }

            return(attributeDeclaration);
        }
Exemple #6
0
        public override AttributeDeclaration GetAttributeDeclaration(Attribute attribute)
        {
            DisplayAttribute     displayAttribute     = (DisplayAttribute)attribute;
            AttributeDeclaration attributeDeclaration = new AttributeDeclaration(typeof(DisplayAttribute));

            // By convention, the attribute parameters are not validated until an attempt is made to
            // access the resources.  We do the following probe merely to trigger this validation process.
            // An InvalidOperationException will be thrown if the attribute is ill-formed.
            Type attributeType = attribute.GetType();

            try
            {
                displayAttribute.GetName();
            }
            catch (InvalidOperationException ex)
            {
                throw new AttributeBuilderException(ex, attributeType, "Name");
            }

            try
            {
                displayAttribute.GetShortName();
            }
            catch (InvalidOperationException ex)
            {
                throw new AttributeBuilderException(ex, attributeType, "ShortName");
            }

            try
            {
                displayAttribute.GetDescription();
            }
            catch (InvalidOperationException ex)
            {
                throw new AttributeBuilderException(ex, attributeType, "Description");
            }

            try
            {
                displayAttribute.GetPrompt();
            }
            catch (InvalidOperationException ex)
            {
                throw new AttributeBuilderException(ex, attributeType, "Prompt");
            }

            // Add AutoGenerateField
            if (displayAttribute.GetAutoGenerateField().HasValue)
            {
                attributeDeclaration.NamedParameters.Add("AutoGenerateField", displayAttribute.AutoGenerateField);
            }

            // Add AutoGenerateFilter
            if (displayAttribute.GetAutoGenerateFilter().HasValue)
            {
                attributeDeclaration.NamedParameters.Add("AutoGenerateFilter", displayAttribute.AutoGenerateFilter);
            }

            // Add Description
            if (!string.IsNullOrEmpty(displayAttribute.Description))
            {
                attributeDeclaration.NamedParameters.Add("Description", displayAttribute.Description);
            }

            // Add GroupName
            if (!string.IsNullOrEmpty(displayAttribute.GroupName))
            {
                attributeDeclaration.NamedParameters.Add("GroupName", displayAttribute.GroupName);
            }

            // Add Name
            if (!string.IsNullOrEmpty(displayAttribute.Name))
            {
                attributeDeclaration.NamedParameters.Add("Name", displayAttribute.Name);
            }

            // Add Order
            if (displayAttribute.GetOrder().HasValue)
            {
                attributeDeclaration.NamedParameters.Add("Order", displayAttribute.Order);
            }

            // Add Prompt
            if (!string.IsNullOrEmpty(displayAttribute.Prompt))
            {
                attributeDeclaration.NamedParameters.Add("Prompt", displayAttribute.Prompt);
            }

            // Add ResourceType
            if (displayAttribute.ResourceType != null)
            {
                attributeDeclaration.NamedParameters.Add("ResourceType", displayAttribute.ResourceType);
            }

            // Add ShortName
            if (!string.IsNullOrEmpty(displayAttribute.ShortName))
            {
                attributeDeclaration.NamedParameters.Add("ShortName", displayAttribute.ShortName);
            }

            return(attributeDeclaration);
        }