public Type GetDefaultType(Attribute attribute, FileAccess access, Type requestedType)
        {
            if (access == FileAccess.Write)
            {
                // TType is OpenType
                // TType is CloudMessage,   String --> CloudMessage

                var openType = OpenType.FromType <TType>();

                // Check for a direct match.
                // Check if there's a converter
                // This is critical when there are no converters, such as if TType is an OpenType
                foreach (var target in _defaultTypes)
                {
                    if (openType.IsMatch(target) ||
                        _converterManager.HasConverter <TAttribute>(target, typeof(TType)))
                    {
                        return(typeof(IAsyncCollector <>).MakeGenericType(target));
                    }
                }

                return(null);
            }
            return(null);
        }
        public IEnumerable <BindingRule> GetRules()
        {
            if (typeof(TTriggerValue).IsPublic)
            {
                yield return(new BindingRule
                {
                    SourceAttribute = typeof(TAttribute),
                    UserType = OpenType.FromType <TTriggerValue>()
                });
            }

            var cm    = (ConverterManager)_converterManager;
            var types = cm.GetPossibleDestinationTypesFromSource(typeof(TAttribute), typeof(TTriggerValue));

            var converters = new Type[] { typeof(TTriggerValue) };

            foreach (OpenType type in types)
            {
                yield return(new BindingRule
                {
                    SourceAttribute = typeof(TAttribute),
                    Converters = converters,
                    UserType = type
                });
            }
        }
        private readonly OpenType _filter; // Filter to only apply to types that match this open type.

        public ItemBindingProvider(
            INameResolver nameResolver,
            Func <TAttribute, Type, Task <IValueBinder> > builder,
            OpenType filter)
        {
            this._nameResolver = nameResolver;
            this._builder      = builder;
            this._filter       = filter;
        }
Пример #4
0
        private readonly OpenType _filter; // Filter to only apply to types that match this open type.

        public ItemBindingProvider(
            IConfiguration configuration,
            INameResolver nameResolver,
            Func <TAttribute, Type, Task <IValueBinder> > builder,
            OpenType filter)
        {
            _configuration = configuration;
            _nameResolver  = nameResolver;
            _builder       = builder;
            _filter        = filter;
        }
        private static void AddRulesForType(OpenType target, List <BindingRule> rules)
        {
            // Use a converter
            var intermediateType = typeof(IAsyncCollector <TType>);

            // IAsyncCollector<T>
            rules.Add(
                new BindingRule
            {
                SourceAttribute = typeof(TAttribute),
                Converters      = MakeArray(intermediateType),
                UserType        = new OpenType.SingleGenericArgOpenType(typeof(IAsyncCollector <>), target)
            });

            // ICollector<T>
            rules.Add(
                new BindingRule
            {
                SourceAttribute = typeof(TAttribute),
                Converters      = MakeArray(intermediateType),
                UserType        = new OpenType.SingleGenericArgOpenType(typeof(ICollector <>), target)
            });

            // out T
            rules.Add(
                new BindingRule
            {
                SourceAttribute = typeof(TAttribute),
                Converters      = MakeArray(intermediateType),
                UserType        = new OpenType.ByRefOpenType(target)
            });

            // out T[]
            rules.Add(
                new BindingRule
            {
                SourceAttribute = typeof(TAttribute),
                Converters      = MakeArray(intermediateType),
                UserType        = new OpenType.ByRefOpenType(new OpenType.ArrayOpenType(target))
            });
        }
Пример #6
0
 public ArrayOpenType(OpenType inner)
 {
     _inner = inner;
 }
Пример #7
0
 public ByRefOpenType(OpenType inner)
 {
     _inner = inner;
 }
Пример #8
0
 public SingleGenericArgOpenType(Type outerType, OpenType inner)
 {
     _inner     = inner;
     _outerType = outerType;
 }
        // Parse the signature to determine which mode this is.
        // Can also check with converter manager to disambiguate some cases.
        private CollectorBindingPattern GetMode(ParameterInfo parameter)
        {
            Type parameterType = parameter.ParameterType;

            if (parameterType.IsGenericType)
            {
                var genericType = parameterType.GetGenericTypeDefinition();
                var elementType = parameterType.GetGenericArguments()[0];

                if (genericType == typeof(IAsyncCollector <>))
                {
                    return(new CollectorBindingPattern(Mode.IAsyncCollector, elementType));
                }
                else if (genericType == typeof(ICollector <>))
                {
                    return(new CollectorBindingPattern(Mode.ICollector, elementType));
                }

                // A different interface. Let another rule try it.
                return(null);
            }

            if (parameter.IsOut)
            {
                // How should "out byte[]" bind?
                // If there's an explicit "byte[] --> TMessage" converter, then that takes precedence.
                // Else, bind over an array of "byte --> TMessage" converters
                Type elementType  = parameter.ParameterType.GetElementType();
                bool hasConverter = this._converterManager.HasConverter <TAttribute>(elementType, typeof(TType));
                if (hasConverter)
                {
                    // out T, where T might be an array
                    return(new CollectorBindingPattern(Mode.OutSingle, elementType));
                }

                if (elementType.IsArray)
                {
                    // out T[]
                    var messageType = elementType.GetElementType();
                    return(new CollectorBindingPattern(Mode.OutArray, messageType));
                }

                var validator = OpenType.FromType <TType>();
                if (validator.IsMatch(elementType))
                {
                    // out T, t is not an array
                    return(new CollectorBindingPattern(Mode.OutSingle, elementType));
                }

                // For out-param ,we don't expect another rule to claim it. So give some rich errors on mismatch.
                if (typeof(IEnumerable).IsAssignableFrom(elementType))
                {
                    throw new InvalidOperationException(
                              "Enumerable types are not supported. Use ICollector<T> or IAsyncCollector<T> instead.");
                }
                else if (typeof(object) == elementType)
                {
                    throw new InvalidOperationException("Object element types are not supported.");
                }
            }

            // No match. Let another rule claim it
            return(null);
        }
            public static ExactBinding <TMessage> TryBuild(
                AsyncCollectorBindingProvider <TAttribute, TType> parent,
                Mode mode,
                BindingProviderContext context)
            {
                var patternMatcher = parent._patternMatcher;

                var parameter       = context.Parameter;
                var attributeSource = TypeUtility.GetResolvedAttribute <TAttribute>(parameter);

                FuncAsyncConverter buildFromAttribute;
                FuncAsyncConverter <TMessage, TType> converter = null;

                // Prefer the shortest route to creating the user type.
                // If TType matches the user type directly, then we should be able to directly invoke the builder in a single step.
                //   TAttribute --> TUserType
                var checker = OpenType.FromType <TType>();

                if (checker.IsMatch(typeof(TMessage)))
                {
                    buildFromAttribute = patternMatcher.TryGetConverterFunc(
                        typeof(TAttribute), typeof(IAsyncCollector <TMessage>));
                }
                else
                {
                    var converterManager = parent._converterManager;

                    // Try with a converter
                    // Find a builder for :   TAttribute --> TType
                    // and then couple with a converter:  TType --> TParameterType
                    converter = converterManager.GetConverter <TMessage, TType, TAttribute>();
                    if (converter == null)
                    {
                        // Preserves legacy behavior. This means we can only have 1 async collector.
                        // However, the collector's builder object can switch.
                        throw NewMissingConversionError(typeof(TMessage));
                    }

                    buildFromAttribute = patternMatcher.TryGetConverterFunc(
                        typeof(TAttribute), typeof(IAsyncCollector <TType>));
                }

                if (buildFromAttribute == null)
                {
                    context.BindingErrors.Add(String.Format(Constants.BindingAssemblyConflictMessage, typeof(TType).AssemblyQualifiedName, typeof(TMessage).AssemblyQualifiedName));
                    return(null);
                }

                ParameterDescriptor param;

                if (parent.BuildParameterDescriptor != null)
                {
                    param = parent.BuildParameterDescriptor(attributeSource, parameter, parent._nameResolver);
                }
                else
                {
                    param = new ParameterDescriptor
                    {
                        Name         = parameter.Name,
                        DisplayHints = new ParameterDisplayHints
                        {
                            Description = "output"
                        }
                    };
                }

                var cloner = new AttributeCloner <TAttribute>(attributeSource, context.BindingDataContract, parent._nameResolver);

                return(new ExactBinding <TMessage>(cloner, param, mode, buildFromAttribute, converter));
            }
        public IEnumerable <BindingRule> GetRules()
        {
            var accessProp = typeof(TAttribute).GetProperty("access", BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase);

            foreach (var type in new Type[]
            {
                typeof(Stream),
            })
            {
                yield return(new BindingRule
                {
                    SourceAttribute = typeof(TAttribute),
                    Filter = FilterNode.NotNull(accessProp), // For stream, Must specify Read vs. Write
                    UserType = OpenType.FromType(type)
                });
            }

            // Read
            foreach (var filter in new FilterNode[]
            {
                FilterNode.IsEqual(accessProp, FileAccess.Read),
                FilterNode.Null(accessProp) // Not write
            })
            {
                foreach (var type in new Type[]
                {
                    typeof(TextReader),
                    typeof(string),
                    typeof(byte[])
                })
                {
                    yield return(new BindingRule
                    {
                        Filter = filter,
                        SourceAttribute = typeof(TAttribute),
                        UserType = OpenType.FromType(type)
                    });
                }
            }

            // Write
            foreach (var filter in new FilterNode[]
            {
                FilterNode.IsEqual(accessProp, FileAccess.Write),
                FilterNode.Null(accessProp) // Not Read
            })
            {
                foreach (var type in new Type[]
                {
                    typeof(TextWriter),
                    typeof(string).MakeByRefType(),
                    typeof(byte[]).MakeByRefType()
                })
                {
                    yield return(new BindingRule
                    {
                        Filter = filter,
                        SourceAttribute = typeof(TAttribute),
                        UserType = OpenType.FromType(type)
                    });
                }
            }
        }
Пример #12
0
            public static ExactBinding TryBuild(
                BindToInputBindingProvider <TAttribute, TType> parent,
                BindingProviderContext context)
            {
                var cm             = parent._converterManager;
                var patternMatcher = parent._patternMatcher;

                var parameter       = context.Parameter;
                var userType        = parameter.ParameterType;
                var attributeSource = TypeUtility.GetResolvedAttribute <TAttribute>(parameter);

                var cloner = new AttributeCloner <TAttribute>(attributeSource, context.BindingDataContract, parent._configuration, parent._nameResolver);

                FuncAsyncConverter buildFromAttribute;
                FuncAsyncConverter converter = null;

                // Prefer the shortest route to creating the user type.
                // If TType matches the user type directly, then we should be able to directly invoke the builder in a single step.
                //   TAttribute --> TUserType
                var checker = OpenType.FromType <TType>();

                if (checker.IsMatch(userType))
                {
                    buildFromAttribute = patternMatcher.TryGetConverterFunc(typeof(TAttribute), userType);
                }
                else
                {
                    // Try with a converter
                    // Find a builder for :   TAttribute --> TType
                    // and then couple with a converter:  TType --> TParameterType
                    converter = cm.GetConverter <TAttribute>(typeof(TType), userType);
                    if (converter == null)
                    {
                        var targetType = typeof(TType);
                        context.BindingErrors.Add(String.Format(Resource.BindingAssemblyConflictMessage, targetType.AssemblyQualifiedName, userType.AssemblyQualifiedName));
                        return(null);
                    }

                    buildFromAttribute = patternMatcher.TryGetConverterFunc(typeof(TAttribute), typeof(TType));
                }

                if (buildFromAttribute == null)
                {
                    return(null);
                }

                ParameterDescriptor param;

                if (parent.BuildParameterDescriptor != null)
                {
                    param = parent.BuildParameterDescriptor(attributeSource, parameter, parent._nameResolver);
                }
                else
                {
                    param = new ParameterDescriptor
                    {
                        Name         = parameter.Name,
                        DisplayHints = new ParameterDisplayHints
                        {
                            Description = "input"
                        }
                    };
                }

                return(new ExactBinding(cloner, param, buildFromAttribute, converter, userType));
            }