Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add binding attribute to converter context #1660

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
fabiocav marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public async ValueTask<FunctionInputBindingResult> BindFunctionInputAsync(Functi
// Return the cached value if BindFunctionInputAsync is called a second time during invocation.
return _inputBindingResult!;
}

IFunctionBindingsFeature functionBindings = context.GetBindings();
var inputBindingCache = context.InstanceServices.GetService<IBindingCache<ConversionResult>>();
var inputConversionFeature = context.Features.Get<IInputConversionFeature>();
Expand Down Expand Up @@ -72,25 +72,12 @@ public async ValueTask<FunctionInputBindingResult> BindFunctionInputAsync(Functi
{
var properties = new Dictionary<string, object>();

// Pass info about specific input converter type defined for this parameter, if present.
if (param.Properties.TryGetValue(PropertyBagKeys.ConverterType, out var converterTypeAssemblyFullName))
{
properties.Add(PropertyBagKeys.ConverterType, converterTypeAssemblyFullName);
}

// Pass info about the flag to allow fallback to default converters defined for this parameter, if present.
if (param.Properties.TryGetValue(PropertyBagKeys.AllowConverterFallback, out var flag))
{
properties.Add(PropertyBagKeys.AllowConverterFallback, flag);
}

// Pass info about input converter types defined for this parameter, if present.
if (param.Properties.TryGetValue(PropertyBagKeys.BindingAttributeSupportedConverters, out var converters))
{
properties.Add(PropertyBagKeys.BindingAttributeSupportedConverters, converters);
}

var converterContext = _converterContextFactory.Create(param.Type, source, context, properties.Count() != 0
AddFunctionParameterPropertyIfPresent(properties, param, PropertyBagKeys.ConverterType);
AddFunctionParameterPropertyIfPresent(properties, param, PropertyBagKeys.AllowConverterFallback);
AddFunctionParameterPropertyIfPresent(properties, param, PropertyBagKeys.BindingAttributeSupportedConverters);
AddFunctionParameterPropertyIfPresent(properties, param, PropertyBagKeys.BindingAttribute);
liliankasem marked this conversation as resolved.
Show resolved Hide resolved

var converterContext = _converterContextFactory.Create(param.Type, source, context, properties.Count() != 0
? properties.ToImmutableDictionary()
: ImmutableDictionary<string, object>.Empty);

Expand Down Expand Up @@ -129,6 +116,14 @@ public async ValueTask<FunctionInputBindingResult> BindFunctionInputAsync(Functi
}
}

private void AddFunctionParameterPropertyIfPresent(IDictionary<string, object> properties, FunctionParameter param, string key)
{
if (param.Properties.TryGetValue(key, out object val))
{
properties.Add(key, val);
}
}

public void Dispose()
{
if (_disposed)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;

namespace Microsoft.Azure.Functions.Worker.Converters
{
/// <summary>
/// Provides extension methods to work with an <see cref="ConverterContext"/> instance.
/// </summary>
public static class ConverterContextExtensions
{
/// <summary>
/// Tries to retrieve the binding attribute from the <see cref="ConverterContext"/>.
/// </summary>
/// <param name="context">The converter context.</param>
/// <param name="bindingAttribute">When this method returns, contains the binding attribute if found; otherwise, <c>null</c>.</param>
/// <returns><c>true</c> if the binding attribute is found in the converter context; otherwise, <c>false</c>.</returns>
public static bool TryGetBindingAttribute<T>(this ConverterContext context, out object? bindingAttribute) where T : Attribute
=> context.Properties.TryGetValue(PropertyBagKeys.BindingAttribute, out bindingAttribute);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace Microsoft.Azure.Functions.Worker.Converters
internal static class PropertyBagKeys
{
internal const string ConverterType = "converterType";
internal const string BindingAttribute = "bindingAttribute";
internal const string AllowConverterFallback = "allowConverterFallback";
internal const string BindingAttributeSupportedConverters = "bindingAttributeSupportedConverters";
}
Expand Down
3 changes: 2 additions & 1 deletion src/DotNetWorker.Grpc/Definition/GrpcFunctionDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,12 @@ public GrpcFunctionDefinition(FunctionLoadRequest loadRequest, IMethodInfoLocato
var output = new Dictionary<string, object>();
bool isInputConverterAttributeAdvertised = false;

output.Add(PropertyBagKeys.BindingAttribute, bindingAttribute);

// ConverterTypesDictionary will be "object" part of the return value - ImmutableDictionary<string, object>
// The dictionary has key of type IInputConverter and value as List of Types supported by the converter.
var converterTypesDictionary = new Dictionary<Type, List<Type>>();


Type type = bindingAttribute.GetType();
var attributes = type.GetCustomAttributes<InputConverterAttribute>();

Expand Down