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

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

            return(argumentBuilder);
        }
Exemple #2
0
 public AsyncCollectorBinding(
     ParameterDescriptor param,
     FuncArgumentBuilder <TAttribute> argumentBuilder,
     AttributeCloner <TAttribute> cloner)
     : base(cloner, param)
 {
     this._argumentBuilder = argumentBuilder;
 }
Exemple #3
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);
        }
Exemple #4
0
        private static FuncArgumentBuilder <TAttribute> BuildOutArrayArgument <TAttribute, TMessage, TMessageSrc>(
            IConverterManager cm,
            Func <TAttribute, IAsyncCollector <TMessage> > buildFromAttribute,
            AttributeCloner <TAttribute> cloner)
            where TAttribute : Attribute
        {
            // Other
            var convert = cm.GetConverter <TMessageSrc, TMessage, TAttribute>();
            FuncArgumentBuilder <TAttribute> argumentBuilder = (attrResolved, context) =>
            {
                IAsyncCollector <TMessage>    raw = buildFromAttribute(attrResolved);
                IAsyncCollector <TMessageSrc> obj = new TypedAsyncCollectorAdapter <TMessageSrc, TMessage, TAttribute>(
                    raw, convert, attrResolved, context);
                string invokeString = cloner.GetInvokeString(attrResolved);
                return(new OutArrayValueProvider <TMessageSrc>(obj, invokeString));
            };

            return(argumentBuilder);
        }
Exemple #5
0
        internal static IBinding BindCollector <TAttribute, TMessage>(
            ParameterInfo parameter,
            INameResolver nameResolver,
            IConverterManager converterManager,
            IReadOnlyDictionary <string, Type> bindingDataContract,
            Func <TAttribute, IAsyncCollector <TMessage> > buildFromAttribute,
            Func <TAttribute, ParameterInfo, INameResolver, ParameterDescriptor> buildParamDescriptor = null,
            Func <TAttribute, ParameterInfo, INameResolver, Task <TAttribute> > hook = null)
            where TAttribute : Attribute
        {
            if (parameter == null)
            {
                throw new ArgumentNullException("parameter");
            }

            Func <TAttribute, Task <TAttribute> > hookWrapper = null;

            if (hook != null)
            {
                hookWrapper = (attr) => hook(attr, parameter, nameResolver);
            }
            TAttribute attributeSource = parameter.GetCustomAttribute <TAttribute>(inherit: false);

            // ctor will do validation and throw.
            var cloner = new AttributeCloner <TAttribute>(attributeSource, bindingDataContract, nameResolver, hookWrapper);

            Type parameterType = parameter.ParameterType;

            FuncArgumentBuilder <TAttribute> argumentBuilder = null;

            // C# reflection trivia: If .IsOut = true, then IsGenericType = false.
            if (parameterType.IsGenericType)
            {
                argumentBuilder = BindAsyncCollectorToInterface(converterManager, buildFromAttribute, cloner, parameterType, argumentBuilder);
            }

            if (parameter.IsOut)
            {
                argumentBuilder = BindAsyncCollectorToOut <TAttribute, TMessage>(parameter, converterManager, buildFromAttribute, cloner);
            }

            if (argumentBuilder == null)
            {
                // Can't bind it.
                return(null);
            }

            ParameterDescriptor param;

            if (buildParamDescriptor != null)
            {
                param = buildParamDescriptor(attributeSource, parameter, nameResolver);
            }
            else
            {
                // If no parameter supplied, use a default.
                param = new ParameterDescriptor
                {
                    Name         = parameter.Name,
                    DisplayHints = new ParameterDisplayHints
                    {
                        Description = "output"
                    }
                };
            }

            return(new AsyncCollectorBinding <TAttribute, TMessage>(param, argumentBuilder, cloner));
        }