How do I use Binder to perform dynamic bindings in my C# Function?

Binder is an advanced binding technique that allows you to perform bindings imperatively in your code as opposed to declaratively via the function.json metadata file. You might need to do this in cases where the computation of binding path or other inputs needs to happen at runtime in your function. Note that when using an Binder parameter, you should not include a corresponding entry in function.json for that parameter.

In the below example, we’re dynamically binding to a blob output. As you can see, because you’re declaring the binding in code, your path info can be computed in any way you wish. Note that you can bind to any of the other raw binding attributes as well (e.g. QueueAttribute/EventHubAttribute/ServiceBusAttribute/etc.) You can also do so iteratively to bind multiple times.

Note that the type parameter passed to BindAsync (in this case TextWriter) must be a type that the target binding supports.

using System;
using System.Net;
using Microsoft.Azure.WebJobs;

public static async Task<HttpResponseMessage> Run(
        HttpRequestMessage req, Binder binder, TraceWriter log)
{
    log.Verbose($"C# HTTP function processed RequestUri={req.RequestUri}");

    // determine the path at runtime in any way you choose
    string path = "samples-output/path";

    using (var writer = await binder.BindAsync<TextWriter>(new BlobAttribute(path)))
    {
        writer.Write("Hello World!!");
    }

    return new HttpResponseMessage(HttpStatusCode.OK); 
}

And here is the corresponding metadata:

{
  "bindings": [
    {
      "name": "req",
      "type": "httpTrigger",
      "direction": "in"
    },
    {
      "name": "res",
      "type": "http",
      "direction": "out"
    }
  ]
}

There are bind overloads that take an array of attributes. In cases where you need to control the target storage account, you pass in a collection of attributes, starting with the binding type attribute (e.g. BlobAttribute) and inlcuding a StorageAccountAttribute instance pointing to the account to use. For example:

var attributes = new Attribute[]
{
    new BlobAttribute(path),
    new StorageAccountAttribute("MyStorageAccount")
};
using (var writer = await binder.BindAsync<TextWriter>(attributes))
{
    writer.Write("Hello World!");
}

Leave a Comment