public static ExactBinding <TMessage> TryBuild( AsyncCollectorBindingProvider <TAttribute, TType> parent, Mode mode, BindingProviderContext context) { var patternMatcher = parent._patternMatcher; var parameter = context.Parameter; TAttribute attributeSource = parameter.GetCustomAttribute <TAttribute>(inherit: false); Func <TAttribute, Task <TAttribute> > hookWrapper = null; if (parent.PostResolveHook != null) { hookWrapper = (attrResolved) => parent.PostResolveHook(attrResolved, parameter, parent._nameResolver); } Func <object, object> buildFromAttribute; FuncConverter <TMessage, TAttribute, 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 = ConverterManager.GetTypeValidator <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) { 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, hookWrapper); return(new ExactBinding <TMessage>(cloner, param, mode, buildFromAttribute, converter)); }
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)); }