in src/Microsoft.Azure.WebJobs.Host/Bindings/Runtime/Binder.cs [93:147]
public virtual async Task<TValue> BindAsync<TValue>(Attribute[] attributes, CancellationToken cancellationToken = default(CancellationToken))
{
var attribute = attributes.First();
var additionalAttributes = attributes.Skip(1).ToArray();
IBinding binding = await _bindingSource.BindAsync<TValue>(attribute, additionalAttributes, cancellationToken);
if (binding == null)
{
throw new InvalidOperationException("No binding found for attribute '" + attribute.GetType() + "'.");
}
// Create a clone of the binding context, so any binding data that was added will be applied to the binding
var ambientBindingContext = new AmbientBindingContext(_bindingSource.AmbientBindingContext.FunctionContext, _bindingData);
var bindingContext = new BindingContext(ambientBindingContext, cancellationToken);
foreach (Attribute attr in attributes)
{
if (attr is SharedMemoryAttribute sharedMemoryAttribute)
{
bindingContext.ValueContext.SharedMemoryMetadata = new SharedMemoryMetadata(sharedMemoryAttribute.MemoryMapName, sharedMemoryAttribute.Count);
break;
}
}
IValueProvider provider = await binding.BindAsync(bindingContext);
if (provider == null)
{
return default(TValue);
}
Debug.Assert(provider.Type == typeof(TValue));
ParameterDescriptor parameterDesciptor = binding.ToParameterDescriptor();
parameterDesciptor.Name = null; // Remove the dummy name "?" used for runtime binding.
// Add even if watchable is null to show parameter descriptor in status.
string value = provider.ToInvokeString();
IWatchable watchable = provider as IWatchable;
_watcher.Add(parameterDesciptor, value, watchable);
IValueBinder binder = provider as IValueBinder;
if (binder != null)
{
_binders.Add(binder);
}
IDisposable disposableProvider = provider as IDisposable;
if (disposableProvider != null)
{
_disposable.Add(disposableProvider);
}
object result = await provider.GetValueAsync();
return (TValue)result;
}