private static Func <TAttribute, IValueProvider> BuildICollectorArgument <TAttribute, TMessage, TMessageSrc>(
            IConverterManager cm,
            Func <TAttribute, IAsyncCollector <TMessage> > buildFromAttribute,
            AttributeCloner <TAttribute> cloner)
            where TAttribute : Attribute
        {
            // Other
            Func <TMessageSrc, TAttribute, TMessage> convert = cm.GetConverter <TMessageSrc, TMessage, TAttribute>();

            if (convert == null)
            {
                ThrowMissingConversionError(typeof(TMessageSrc));
            }
            Func <TAttribute, IValueProvider> argumentBuilder = (attrResolved) =>
            {
                IAsyncCollector <TMessage>    raw = buildFromAttribute(attrResolved);
                IAsyncCollector <TMessageSrc> obj = new TypedAsyncCollectorAdapter <TMessageSrc, TMessage, TAttribute>(
                    raw, convert, attrResolved);
                ICollector <TMessageSrc> obj2 = new SyncAsyncCollectorAdapter <TMessageSrc>(obj);
                string invokeString           = cloner.GetInvokeString(attrResolved);
                return(new AsyncCollectorValueProvider <ICollector <TMessageSrc>, TMessage>(obj2, raw, invokeString));
            };

            return(argumentBuilder);
        }
示例#2
0
        // Helper to bind an IAsyncCollector<TMessage> raw object to an IAsyncCollector<TUser> or ICollecter<TUser> and invoke converter manager as needed.
        private static FuncArgumentBuilder <TAttribute> BindAsyncCollectorToInterface <TAttribute, TMessage>(
            IConverterManager converterManager,
            Func <TAttribute, IAsyncCollector <TMessage> > buildFromAttribute,
            AttributeCloner <TAttribute> cloner, Type parameterType,
            FuncArgumentBuilder <TAttribute> argumentBuilder) where TAttribute : Attribute
        {
            var genericType = parameterType.GetGenericTypeDefinition();
            var elementType = parameterType.GetGenericArguments()[0];

            if (genericType == typeof(IAsyncCollector <>))
            {
                if (elementType == typeof(TMessage))
                {
                    // Bind to IAsyncCollector<TMessage>. This is the "purest" binding, no adaption needed.
                    argumentBuilder = (attrResolved, context) =>
                    {
                        IAsyncCollector <TMessage> raw = buildFromAttribute(attrResolved);
                        var invokeString = cloner.GetInvokeString(attrResolved);

                        return(new AsyncCollectorValueProvider <IAsyncCollector <TMessage>, TMessage>(raw, raw, invokeString));
                    };
                }
                else
                {
                    // Bind to IAsyncCollector<T>
                    // Get a converter from T to TMessage
                    argumentBuilder = DynamicInvokeBuildIAsyncCollectorArgument(elementType, converterManager, buildFromAttribute, cloner);
                }
            }
            else if (genericType == typeof(ICollector <>))
            {
                if (elementType == typeof(TMessage))
                {
                    // Bind to ICollector<TMessage> This just needs an Sync/Async wrapper
                    argumentBuilder = (attrResolved, context) =>
                    {
                        IAsyncCollector <TMessage> raw = buildFromAttribute(attrResolved);
                        var invokeString          = cloner.GetInvokeString(attrResolved);
                        ICollector <TMessage> obj = new SyncAsyncCollectorAdapter <TMessage>(raw);
                        return(new AsyncCollectorValueProvider <ICollector <TMessage>, TMessage>(obj, raw, invokeString));
                    };
                }
                else
                {
                    // Bind to ICollector<T>.
                    // This needs both a conversion from T to TMessage and an Sync/Async wrapper
                    argumentBuilder = DynamicInvokeBuildICollectorArgument(elementType, converterManager, buildFromAttribute, cloner);
                }
            }

            return(argumentBuilder);
        }
        private static Func <TContext, ValueBindingContext, IValueProvider> BuildICollectorArgument <TContext, TMessageSrc, TMessage>(
            IConverterManager cm,
            Func <TContext, ValueBindingContext, IAsyncCollector <TMessage> > builder,
            string invokeString)
        {
            // Other
            Func <TMessageSrc, TMessage> convert = cm.GetConverter <TMessageSrc, TMessage>();
            Func <TContext, ValueBindingContext, IValueProvider> argumentBuilder = (context, valueBindingContext) =>
            {
                IAsyncCollector <TMessage>    raw  = builder(context, valueBindingContext);
                IAsyncCollector <TMessageSrc> obj  = new TypedAsyncCollectorAdapter <TMessageSrc, TMessage>(raw, convert);
                ICollector <TMessageSrc>      obj2 = new SyncAsyncCollectorAdapter <TMessageSrc>(obj);
                return(new AsyncCollectorValueProvider <ICollector <TMessageSrc>, TMessage>(obj2, raw, invokeString));
            };

            return(argumentBuilder);
        }
示例#4
0
            // Get a ValueProvider that's in the right mode.
            private static IValueProvider CoerceValueProvider(Mode mode, string invokeString, IAsyncCollector <TMessage> collector)
            {
                switch (mode)
                {
                case Mode.IAsyncCollector:
                    return(new AsyncCollectorValueProvider <IAsyncCollector <TMessage>, TMessage>(collector, collector, invokeString));

                case Mode.ICollector:
                    ICollector <TMessage> syncCollector = new SyncAsyncCollectorAdapter <TMessage>(collector);
                    return(new AsyncCollectorValueProvider <ICollector <TMessage>, TMessage>(syncCollector, collector, invokeString));

                case Mode.OutArray:
                    return(new OutArrayValueProvider <TMessage>(collector, invokeString));

                case Mode.OutSingle:
                    return(new OutValueProvider <TMessage>(collector, invokeString));

                default:
                    throw new NotImplementedException($"mode ${mode} not implemented");
                }
            }
        public static IBinding BindCollector <TMessage, TContext>(
            ParameterInfo parameter,
            IConverterManager converterManager,
            Func <TContext, ValueBindingContext, IAsyncCollector <TMessage> > builder,
            string invokeString,
            Func <string, TContext> invokeStringBinder)
        {
            if (builder == null)
            {
                throw new ArgumentNullException("builder");
            }
            if (invokeStringBinder == null)
            {
                throw new ArgumentNullException("invokeStringBinder");
            }
            if (parameter == null)
            {
                throw new ArgumentNullException("parameter");
            }

            Type parameterType = parameter.ParameterType;

            Func <TContext, ValueBindingContext, IValueProvider> argumentBuilder = null;

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

                if (genericType == typeof(IAsyncCollector <>))
                {
                    if (elementType == typeof(TMessage))
                    {
                        // Bind to IAsyncCollector<TMessage>. This is the "purest" binding, no adaption needed.
                        argumentBuilder = (context, valueBindingContext) =>
                        {
                            IAsyncCollector <TMessage> raw = builder(context, valueBindingContext);
                            return(new AsyncCollectorValueProvider <IAsyncCollector <TMessage>, TMessage>(raw, raw, invokeString));
                        };
                    }
                    else
                    {
                        // Bind to IAsyncCollector<T>
                        // Get a converter from T to TMessage
                        argumentBuilder = DynamicInvokeBuildIAsyncCollectorArgument(elementType, converterManager, builder, invokeString);
                    }
                }
                else if (genericType == typeof(ICollector <>))
                {
                    if (elementType == typeof(TMessage))
                    {
                        // Bind to ICollector<TMessage> This just needs an Sync/Async wrapper
                        argumentBuilder = (context, valueBindingContext) =>
                        {
                            IAsyncCollector <TMessage> raw = builder(context, valueBindingContext);
                            ICollector <TMessage>      obj = new SyncAsyncCollectorAdapter <TMessage>(raw);
                            return(new AsyncCollectorValueProvider <ICollector <TMessage>, TMessage>(obj, raw, invokeString));
                        };
                    }
                    else
                    {
                        // Bind to ICollector<T>.
                        // This needs both a conversion from T to TMessage and an Sync/Async wrapper
                        argumentBuilder = DynamicInvokeBuildICollectorArgument(elementType, converterManager, builder, invokeString);
                    }
                }
            }

            if (parameter.IsOut)
            {
                Type elementType = parameter.ParameterType.GetElementType();

                if (elementType.IsArray)
                {
                    if (elementType == typeof(TMessage[]))
                    {
                        argumentBuilder = (context, valueBindingContext) =>
                        {
                            IAsyncCollector <TMessage> raw = builder(context, valueBindingContext);
                            return(new OutArrayValueProvider <TMessage>(raw, invokeString));
                        };
                    }
                    else
                    {
                        // out TMessage[]
                        var e2 = elementType.GetElementType();
                        argumentBuilder = DynamicBuildOutArrayArgument(e2, converterManager, builder, invokeString);
                    }
                }
                else
                {
                    // Single enqueue
                    //    out TMessage
                    if (elementType == typeof(TMessage))
                    {
                        argumentBuilder = (context, valueBindingContext) =>
                        {
                            IAsyncCollector <TMessage> raw = builder(context, valueBindingContext);
                            return(new OutValueProvider <TMessage>(raw, invokeString));
                        };
                    }
                    else
                    {
                        // use JSon converter
                        // out T
                        argumentBuilder = DynamicInvokeBuildOutArgument(elementType, converterManager, builder, invokeString);
                    }
                }
            }

            if (argumentBuilder != null)
            {
                ParameterDescriptor param = new ParameterDescriptor
                {
                    Name         = parameter.Name,
                    DisplayHints = new ParameterDisplayHints
                    {
                        Description = "output"
                    }
                };

                var initialClient = invokeStringBinder(invokeString);
                return(new AsyncCollectorBinding <TMessage, TContext>(initialClient, argumentBuilder, param, invokeStringBinder));
            }

            string msg = string.Format(CultureInfo.CurrentCulture, "Can't bind to {0}.", parameter);

            throw new InvalidOperationException(msg);
        }