Пример #1
0
        public void GetPolicy_Returns_SpecifiedPolicy()
        {
            PropertyInfo propInfo = typeof(AttributeWithResolutionPolicy).GetProperty(nameof(AttributeWithResolutionPolicy.PropWithPolicy));

            IResolutionPolicy policy = AttributeCloner <AttributeWithResolutionPolicy> .GetPolicy(propInfo);

            Assert.IsType <TestResolutionPolicy>(policy);
        }
        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);
        }
Пример #3
0
        private static string TemplateBind(IResolutionPolicy policy, PropertyInfo prop, Attribute attr, BindingTemplate template, IReadOnlyDictionary <string, object> bindingData)
        {
            if (bindingData == null)
            {
                return(template?.Pattern);
            }

            return(policy.TemplateBind(prop, attr, template, bindingData));
        }
Пример #4
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));
        }
Пример #5
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));

            IResolutionPolicy policy = AttributeCloner <AttributeWithResolutionPolicy> .GetPolicy(propInfo);

            Assert.IsType <Host.Bindings.ODataFilterResolutionPolicy>(policy);
        }
        private static string TemplateBind(IResolutionPolicy policy, PropertyInfo prop, Attribute attr, BindingTemplate template, BindingData bindingData, Validator validator)
        {
            if (bindingData == null)
            {
                // Skip validation if no binding data provided. We can't do the { } substitutions.
                return(template?.Pattern);
            }

            var newValue = policy.TemplateBind(prop, attr, template, bindingData);

            validator(newValue);
            return(newValue);
        }
        // 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));
        }
Пример #8
0
        public AttributeCloner(
            TAttribute source,
            IReadOnlyDictionary <string, Type> bindingDataContract,
            INameResolver nameResolver = null,
            Func <TAttribute, Task <TAttribute> > hook = null)
        {
            _hook        = hook;
            nameResolver = nameResolver ?? new EmptyNameResolver();
            _source      = source;

            Type t = typeof(TAttribute);

            Dictionary <string, PropertyInfo> availableParams = new Dictionary <string, PropertyInfo>(StringComparer.OrdinalIgnoreCase);

            foreach (var prop in t.GetProperties(BindingFlags.Instance | BindingFlags.Public))
            {
                var objValue = prop.GetValue(_source);
                if (objValue != null)
                {
                    availableParams[prop.Name] = prop;
                }
            }

            int longestMatch = -1;

            // Pick the ctor with the longest parameter list where all parameters are matched.
            var ctors = t.GetConstructors(BindingFlags.Public | BindingFlags.Instance);

            foreach (var ctor in ctors)
            {
                var ps  = ctor.GetParameters();
                int len = ps.Length;

                var getArgFuncs = new Func <IReadOnlyDictionary <string, object>, object> [len];

                bool hasAllParameters = true;
                for (int i = 0; i < len; i++)
                {
                    var          p        = ps[i];
                    PropertyInfo propInfo = null;
                    if (!availableParams.TryGetValue(p.Name, out propInfo))
                    {
                        hasAllParameters = false;
                        break;
                    }

                    BindingTemplate template;
                    if (TryCreateAutoResolveBindingTemplate(propInfo, nameResolver, out template))
                    {
                        IResolutionPolicy policy = GetPolicy(propInfo);
                        template.ValidateContractCompatibility(bindingDataContract);
                        getArgFuncs[i] = (bindingData) => TemplateBind(policy, propInfo, source, template, bindingData);
                    }
                    else
                    {
                        var propValue = propInfo.GetValue(_source);
                        getArgFuncs[i] = (bindingData) => propValue;
                    }
                }

                if (hasAllParameters)
                {
                    if (len > longestMatch)
                    {
                        var setProperties = new List <Action <TAttribute, IReadOnlyDictionary <string, object> > >();

                        // Record properties too.
                        foreach (var prop in t.GetProperties(BindingFlags.Instance | BindingFlags.Public))
                        {
                            if (!prop.CanWrite)
                            {
                                continue;
                            }

                            BindingTemplate template;
                            if (TryCreateAutoResolveBindingTemplate(prop, nameResolver, out template))
                            {
                                IResolutionPolicy policy = GetPolicy(prop);
                                template.ValidateContractCompatibility(bindingDataContract);
                                setProperties.Add((newAttr, bindingData) => prop.SetValue(newAttr, TemplateBind(policy, prop, newAttr, template, bindingData)));
                            }
                            else
                            {
                                var objValue = prop.GetValue(_source);
                                setProperties.Add((newAttr, bindingData) => prop.SetValue(newAttr, objValue));
                            }
                        }

                        _setProperties      = setProperties.ToArray();
                        _bestCtor           = ctor;
                        longestMatch        = len;
                        _bestCtorArgBuilder = getArgFuncs;
                    }
                }
            }

            if (_bestCtor == null)
            {
                // error!!!
                throw new InvalidOperationException("Can't figure out which ctor to call.");
            }
        }