Dynamic Binding in Azure Functions with Imperative Runtime Bindings

When creating precompiled Azure Functions, bindings (such as a blob output bindings) can be declared in the function code, for example the following code defines a blob output binding:


This binding creates a new blob with a random (GUID) name. This style of binding is called declarative binding, the binding details are declared as part of the binding attribute.

In addition to declarative binding, Azure Functions also offers imperative binding. With this style of binding, the details of the binding can be chosen at runtime. These details could be derived from the incoming function trigger data or from an external place such as a configuration value or database item

To create imperative bindings, rather than using a specific binding attribute, a parameter of type IBinder is used. At runtime, a binding can be created (such as a blob binding, queue binding, etc.) using this IBinder. The Bind<T> method of the IBinder can be used with T representing an input/output type that is supported by the binding you intend to use.

The following code shows imperative binding in action. In this example blobs are created and the blob path is derived from the incoming JSON data, namely the category.

public static class CreateToDoItem
    public static async Task<HttpResponseMessage> Run(
        [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)]HttpRequestMessage req,
        IBinder binder,
        TraceWriter log)
        ToDoItem item = await req.Content.ReadAsAsync<ToDoItem>();
        item.Id = Guid.NewGuid().ToString();

        BlobAttribute dynamicBlobBinding = new BlobAttribute(blobPath: $"todo/{item.Category}/{item.Id}");

        using (var writer = binder.Bind<TextWriter>(dynamicBlobBinding))

        return req.CreateResponse(HttpStatusCode.OK, "Added " + item.Description);

If the following 2 POSTS are made:

    "Description" : "Lift weights",
    "Category" : "Gym"
    "Description" : "Feed the dog",
    "Category" : "Home"

Then 2 blobs will be output with the following paths - note the random filenames and imperatively-bound paths: Gym and Home :

Comments (2) -

  • James Webster

    3/7/2018 11:24:13 PM | Reply

    Probably worth making clear that this applies to output bindings only... unless you have an example where input bindings can be established imperatively? It couldn't happen inside the function itself, but outside in some sort of configuration code.

    • Jason Roberts

      3/9/2018 5:48:24 AM | Reply

      Thanks James, you can read an input blob based on the filename contained in a message if using a [QueueTrigger] by using the special binding {queueTrigger} - e.g.

      public static void Run(
                  [QueueTrigger("remove-category", Connection = "")]string inputBlobPath,
                  [Blob("queueTrigger}", FileAccess.Read)] Stream blobItemToRead,
                  TraceWriter log)

Add comment