Azure Functions Programming Model (C#)

This document details the programming model for developing C# Azure Functions. Understanding this model is crucial for writing efficient, maintainable, and scalable serverless applications on Azure.

Core Concepts

Function Definition

A C# Azure Function is typically defined as a static method within a class. This method is decorated with attributes that define its behavior, triggers, and bindings.

Triggers

A trigger defines how a function is invoked. It specifies the event that causes the function to run. Common triggers include HTTP requests, timer events, and messages arriving in a queue.


using Microsoft.Azure.Functions.Worker;

namespace MyFunctionApp
{
    public static class HttpTriggerCSharp
    {
        [Function("HttpTriggerCSharp")]
        public static void Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req,
            FunctionContext context)
        {
            // Function logic here
            Console.WriteLine("C# HTTP trigger function processed a request.");
        }
    }
}
        

Bindings

Bindings connect your function to other Azure services or external data sources without requiring you to write explicit SDK code. They can be used for input (providing data to your function) or output (sending data from your function).

Input Bindings

Input bindings supply data to your function when it executes. For example, an input binding can retrieve a blob from Azure Blob Storage or a document from Cosmos DB.

Output Bindings

Output bindings allow your function to send data to another service. For example, an output binding can write a message to an Azure Service Bus queue or insert a record into a database.


using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;
using System.Net;

namespace MyFunctionApp
{
    public static class CosmosDbOutputBinding
    {
        [Function("CosmosDbOutputBinding")]
        [CosmosDBOutput(
            databaseName: "MyDatabase",
            containerName: "MyContainer",
            Connection = "CosmosDbConnection")]
        public static MyDocument Run(
            [HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequestData req,
            FunctionContext context,
            [FromBody] MyDocument inputDocument)
        {
            var logger = context.GetLogger();
            logger.LogInformation("C# function to process input and write to Cosmos DB triggered.");

            // You can modify the inputDocument before returning it
            inputDocument.Id = Guid.NewGuid().ToString(); // Example: Assign a new ID

            return inputDocument;
        }
    }

    // Define your document structure
    public class MyDocument
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
    }
}
        

The FunctionContext

The FunctionContext object provides access to essential information about the current function invocation, including logging, configuration, and binding data.

Logging

You can obtain an ILogger instance from the FunctionContext to log messages during your function's execution. This is crucial for debugging and monitoring.

Note: In the .NET 7+ isolated worker model, you inject ILogger directly into your function signature instead of using FunctionContext.GetLogger for typical logging. However, FunctionContext remains vital for accessing other invocation-specific details.

Function Types

HTTP Triggered Functions

These functions are invoked via HTTP requests and typically handle webhooks, API endpoints, or simple web services.

Timer Triggered Functions

These functions run on a schedule defined by a CRON expression, suitable for background tasks or periodic operations.

Queue/Blob/Service Bus Triggered Functions

These functions are triggered by events in Azure Storage queues, blob containers, or Service Bus topics/queues, enabling event-driven architectures.

Best Practices

Tip: For .NET 7 and later, the isolated worker model is the recommended approach for Azure Functions development in C#. It offers better performance and a more conventional .NET development experience.