public static ExactBinding <TUserType> TryBuild( BindToInputBindingProvider <TAttribute, TType> parent, BindingProviderContext context) { var cm = parent._converterManager; 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); } var cloner = new AttributeCloner <TAttribute>(attributeSource, context.BindingDataContract, parent._nameResolver, hookWrapper); Func <object, object> buildFromAttribute; FuncConverter <TType, TAttribute, TUserType> 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(TUserType))) { buildFromAttribute = patternMatcher.TryGetConverterFunc(typeof(TAttribute), typeof(TUserType)); } else { // Try with a converter // Find a builder for : TAttribute --> TType // and then couple with a converter: TType --> TParameterType converter = cm.GetConverter <TType, TUserType, TAttribute>(); if (converter == null) { 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 <TUserType>(cloner, param, buildFromAttribute, converter)); }
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)); }