Ejemplo n.º 1
0
        // transforms binding data to appropriate resolver (appsetting, autoresolve, or originalValue)
        private BindingDataResolver GetResolver(PropertyInfo propInfo, INameResolver nameResolver, BindingDataContract contract)
        {
            object originalValue = propInfo.GetValue(_source);
            AppSettingAttribute  appSettingAttr  = propInfo.GetCustomAttribute <AppSettingAttribute>();
            AutoResolveAttribute autoResolveAttr = propInfo.GetCustomAttribute <AutoResolveAttribute>();

            if (appSettingAttr != null && autoResolveAttr != null)
            {
                throw new InvalidOperationException($"Property '{propInfo.Name}' cannot be annotated with both AppSetting and AutoResolve.");
            }

            // first try to resolve with app setting
            if (appSettingAttr != null)
            {
                return(GetAppSettingResolver((string)originalValue, appSettingAttr, nameResolver, propInfo));
            }
            // try to resolve with auto resolve ({...}, %...%)
            if (autoResolveAttr != null && originalValue != null)
            {
                _autoResolves[propInfo] = autoResolveAttr;
                return(GetTemplateResolver((string)originalValue, autoResolveAttr, nameResolver, propInfo, contract));
            }
            // resolve the original value
            return((newAttr, bindingData) => originalValue);
        }
Ejemplo n.º 2
0
        internal static IResolutionPolicy GetPolicy(PropertyInfo propInfo)
        {
            AutoResolveAttribute autoResolveAttribute = propInfo.GetCustomAttribute <AutoResolveAttribute>();

            var formatterType = autoResolveAttribute.ResolutionPolicyType;

            if (formatterType != null)
            {
                // Special-case Table as there is no way to declare this ResolutionPolicy
                // and use BindingTemplate in the Core assembly
                if (formatterType == typeof(WebJobs.ODataFilterResolutionPolicy))
                {
                    return(new ODataFilterResolutionPolicy());
                }

                if (!typeof(IResolutionPolicy).IsAssignableFrom(formatterType))
                {
                    throw new InvalidOperationException($"The {nameof(AutoResolveAttribute.ResolutionPolicyType)} on {propInfo.Name} must derive from {typeof(IResolutionPolicy).Name}.");
                }

                try
                {
                    var obj = Activator.CreateInstance(formatterType);
                    return((IResolutionPolicy)obj);
                }
                catch (MissingMethodException)
                {
                    throw new InvalidOperationException($"The {nameof(AutoResolveAttribute.ResolutionPolicyType)} on {propInfo.Name} must derive from {typeof(IResolutionPolicy).Name} and have a default constructor.");
                }
            }

            // return the default policy
            return(new DefaultResolutionPolicy());
        }
        public void GetPolicy_Throws_IfPolicyHasNoDefaultConstructor()
        {
            PropertyInfo              propInfo = typeof(AttributeWithResolutionPolicy).GetProperty(nameof(AttributeWithResolutionPolicy.PropWithConstructorlessPolicy));
            AutoResolveAttribute      attr     = propInfo.GetCustomAttribute <AutoResolveAttribute>();
            InvalidOperationException ex       = Assert.Throws <InvalidOperationException>(() => AttributeCloner <AttributeWithResolutionPolicy> .GetPolicy(attr.ResolutionPolicyType, propInfo));

            Assert.Equal($"The {nameof(AutoResolveAttribute.ResolutionPolicyType)} on {nameof(AttributeWithResolutionPolicy.PropWithConstructorlessPolicy)} must derive from {typeof(IResolutionPolicy).Name} and have a default constructor.", ex.Message);
        }
        public void GetPolicy_Throws_IfPolicyDoesNotImplementInterface()
        {
            PropertyInfo              propInfo = typeof(AttributeWithResolutionPolicy).GetProperty(nameof(AttributeWithResolutionPolicy.PropWithInvalidPolicy));
            AutoResolveAttribute      attr     = propInfo.GetCustomAttribute <AutoResolveAttribute>();
            InvalidOperationException ex       = Assert.Throws <InvalidOperationException>(() => AttributeCloner <AttributeWithResolutionPolicy> .GetPolicy(attr.ResolutionPolicyType, propInfo));

            Assert.Equal($"The {nameof(AutoResolveAttribute.ResolutionPolicyType)} on {nameof(AttributeWithResolutionPolicy.PropWithInvalidPolicy)} must derive from {typeof(IResolutionPolicy).Name}.", ex.Message);
        }
        public void GetPolicy_ReturnsDefault_WhenNoSpecifiedPolicy()
        {
            PropertyInfo         propInfo = typeof(AttributeWithResolutionPolicy).GetProperty(nameof(AttributeWithResolutionPolicy.PropWithoutPolicy));
            AutoResolveAttribute attr     = propInfo.GetCustomAttribute <AutoResolveAttribute>();
            IResolutionPolicy    policy   = AttributeCloner <AttributeWithResolutionPolicy> .GetPolicy(attr.ResolutionPolicyType, propInfo);

            Assert.IsType <DefaultResolutionPolicy>(policy);
        }
Ejemplo n.º 6
0
        public void GetPolicy_ReturnsODataFilterPolicy_ForMarkerType()
        {
            // This is a special-case marker type to handle TableAttribute.Filter. We cannot directly list ODataFilterResolutionPolicy
            // because BindingTemplate doesn't exist in the core assembly.
            PropertyInfo propInfo = typeof(AttributeWithResolutionPolicy).GetProperty(nameof(AttributeWithResolutionPolicy.PropWithMarkerPolicy));

            AutoResolveAttribute attr   = propInfo.GetCustomAttribute <AutoResolveAttribute>();
            IResolutionPolicy    policy = AttributeCloner <AttributeWithResolutionPolicy> .GetPolicy(attr.ResolutionPolicyType, propInfo);

            Assert.IsType <Host.Bindings.ODataFilterResolutionPolicy>(policy);
        }
Ejemplo n.º 7
0
        // transforms binding data to appropriate resolver (appsetting, autoresolve, or originalValue)
        private BindingDataResolver GetResolver(PropertyInfo propInfo, INameResolver nameResolver, BindingDataContract contract)
        {
            // Do the attribute lookups once upfront, and then cache them (via func closures) for subsequent runtime usage.
            object originalValue = propInfo.GetValue(_source);
            ConnectionStringAttribute connStrAttr     = propInfo.GetCustomAttribute <ConnectionStringAttribute>();
            AppSettingAttribute       appSettingAttr  = propInfo.GetCustomAttribute <AppSettingAttribute>();
            AutoResolveAttribute      autoResolveAttr = propInfo.GetCustomAttribute <AutoResolveAttribute>();
            Validator validator = GetValidatorFunc(propInfo, appSettingAttr != null);

            if (appSettingAttr == null && autoResolveAttr == null && connStrAttr == null)
            {
                validator(originalValue);

                // No special attributes, treat as literal.
                return((newAttr, bindingData) => originalValue);
            }

            int attrCount = new Attribute[] { connStrAttr, appSettingAttr, autoResolveAttr }.Count(a => a != null);

            if (attrCount > 1)
            {
                throw new InvalidOperationException($"Property '{propInfo.Name}' can only be annotated with one of the types {nameof(AppSettingAttribute)}, {nameof(AutoResolveAttribute)}, and {nameof(ConnectionStringAttribute)}.");
            }

            // attributes only work on string properties.
            if (propInfo.PropertyType != typeof(string))
            {
                throw new InvalidOperationException($"{nameof(ConnectionStringAttribute)}, {nameof(AutoResolveAttribute)}, or {nameof(AppSettingAttribute)} property '{propInfo.Name}' must be of type string.");
            }

            var str = (string)originalValue;

            // first try to resolve with connection string
            if (connStrAttr != null)
            {
                return(GetConfigurationResolver(str, connStrAttr.Default, propInfo, validator, s => _configuration.GetConnectionStringOrSetting(nameResolver.ResolveWholeString(s))));
            }

            // then app setting
            if (appSettingAttr != null)
            {
                return(GetConfigurationResolver(str, appSettingAttr.Default, propInfo, validator, s => _configuration[s]));
            }

            // Must have an [AutoResolve]
            // try to resolve with auto resolve ({...}, %...%)
            return(GetAutoResolveResolver(str, autoResolveAttr, nameResolver, propInfo, contract, validator));
        }
Ejemplo n.º 8
0
        private bool TryCreateAutoResolveBindingTemplate(PropertyInfo propInfo, INameResolver nameResolver, out BindingTemplate template)
        {
            template = null;

            AutoResolveAttribute attr = propInfo.GetCustomAttribute <AutoResolveAttribute>();

            // Return false if there is no attribute on this property.
            if (attr == null)
            {
                return(false);
            }

            string originalValue = (string)propInfo.GetValue(_source);

            // Return false if the property value is null.
            if (originalValue == null)
            {
                return(false);
            }

            string resolvedValue;

            if (!attr.AllowTokens)
            {
                resolvedValue = nameResolver.Resolve(originalValue);

                // If a value is non-null and cannot be found, we throw to match the behavior
                // when %% values are not found.
                if (resolvedValue == null)
                {
                    string msg = string.Format(CultureInfo.CurrentCulture, "'{0}' does not resolve to a value.", originalValue);
                    throw new InvalidOperationException(msg);
                }
            }
            else
            {
                resolvedValue = nameResolver.ResolveWholeString(originalValue);
            }

            template = BindingTemplate.FromString(resolvedValue);

            return(true);
        }
 // Apply AutoResolve attribute
 internal BindingDataResolver GetAutoResolveResolver(string originalValue, AutoResolveAttribute autoResolveAttr, INameResolver nameResolver, PropertyInfo propInfo, BindingDataContract contract, Validator validator)
 {
     if (string.IsNullOrWhiteSpace(originalValue))
     {
         if (autoResolveAttr.Default != null)
         {
             return(GetBuiltinTemplateResolver(autoResolveAttr.Default, nameResolver, validator));
         }
         else
         {
             validator(originalValue);
             return((newAttr, bindingData) => originalValue);
         }
     }
     else
     {
         _autoResolves[propInfo] = autoResolveAttr;
         return(GetTemplateResolver(originalValue, autoResolveAttr, nameResolver, propInfo, contract, validator));
     }
 }
Ejemplo n.º 10
0
        internal static bool TryAutoResolveValue(TAttribute attribute, PropertyInfo propInfo, INameResolver nameResolver, out string resolvedValue)
        {
            resolvedValue = null;

            AutoResolveAttribute attr = propInfo.GetCustomAttribute <AutoResolveAttribute>();

            if (attr == null)
            {
                return(false);
            }

            string originalValue = (string)propInfo.GetValue(attribute);

            if (originalValue == null)
            {
                return(false);
            }

            if (!attr.AllowTokens)
            {
                resolvedValue = nameResolver.Resolve(originalValue);

                // If a value is non-null and cannot be found, we throw to match the behavior
                // when %% values are not found in ResolveWholeString below.
                if (resolvedValue == null)
                {
                    // It's important that we only log the attribute property name, not the actual value to ensure
                    // that in cases where users accidentally use a secret key *value* rather than indirect setting name
                    // that value doesn't get written to logs.
                    throw new InvalidOperationException($"Unable to resolve value for property '{propInfo.DeclaringType.Name}.{propInfo.Name}'.");
                }
            }
            else
            {
                // The logging consideration above doesn't apply in this case, since only tokens wrapped
                // in %% characters will be resolved, so they are less likely to include a secret value.
                resolvedValue = nameResolver.ResolveWholeString(originalValue);
            }

            return(true);
        }
        // transforms binding data to appropriate resolver (appsetting, autoresolve, or originalValue)
        private BindingDataResolver GetResolver(PropertyInfo propInfo, INameResolver nameResolver, BindingDataContract contract)
        {
            // Do the attribute lookups once upfront, and then cache them (via func closures) for subsequent runtime usage.
            object originalValue = propInfo.GetValue(_source);
            AppSettingAttribute  appSettingAttr  = propInfo.GetCustomAttribute <AppSettingAttribute>();
            AutoResolveAttribute autoResolveAttr = propInfo.GetCustomAttribute <AutoResolveAttribute>();
            Validator            validator       = GetValidatorFunc(propInfo, appSettingAttr != null);

            if (appSettingAttr == null && autoResolveAttr == null)
            {
                validator(originalValue);

                // No special attributes, treat as literal.
                return((newAttr, bindingData) => originalValue);
            }

            if (appSettingAttr != null && autoResolveAttr != null)
            {
                throw new InvalidOperationException($"Property '{propInfo.Name}' cannot be annotated with both AppSetting and AutoResolve.");
            }

            // attributes only work on string properties.
            if (propInfo.PropertyType != typeof(string))
            {
                throw new InvalidOperationException($"AutoResolve or AppSetting property '{propInfo.Name}' must be of type string.");
            }
            var str = (string)originalValue;

            // first try to resolve with app setting
            if (appSettingAttr != null)
            {
                return(GetAppSettingResolver(str, appSettingAttr, nameResolver, propInfo, validator));
            }

            // Must have an [AutoResolve]
            // try to resolve with auto resolve ({...}, %...%)
            return(GetAutoResolveResolver(str, autoResolveAttr, nameResolver, propInfo, contract, validator));
        }
Ejemplo n.º 12
0
        // AutoResolve
        internal static BindingDataResolver GetTemplateResolver(string originalValue, AutoResolveAttribute attr, INameResolver nameResolver, PropertyInfo propInfo, BindingDataContract contract)
        {
            string            resolvedValue = nameResolver.ResolveWholeString(originalValue);
            var               template      = BindingTemplate.FromString(resolvedValue);
            IResolutionPolicy policy        = GetPolicy(attr.ResolutionPolicyType, propInfo);

            template.ValidateContractCompatibility(contract);
            return((newAttr, bindingData) => TemplateBind(policy, propInfo, newAttr, template, bindingData));
        }
        // AutoResolve
        internal static BindingDataResolver GetTemplateResolver(string originalValue, AutoResolveAttribute attr, INameResolver nameResolver, PropertyInfo propInfo, BindingDataContract contract, Validator validator)
        {
            string resolvedValue = nameResolver.ResolveWholeString(originalValue);
            var    template      = BindingTemplate.FromString(resolvedValue);

            if (!template.HasParameters)
            {
                // No { } tokens, bind eagerly up front.
                validator(resolvedValue);
            }

            IResolutionPolicy policy = GetPolicy(attr.ResolutionPolicyType, propInfo);

            template.ValidateContractCompatibility(contract);
            return((newAttr, bindingData) => TemplateBind(policy, propInfo, newAttr, template, bindingData, validator));
        }