Isaac.

Azure Functions with .NET

Build serverless applications with Azure Functions.

By EMEPublished: February 20, 2025
azure functionsserverlessdotnetautomationevent-driven

A Simple Analogy

Azure Functions are like hiring a chef to work only when you need them. No salary when not cooking, pay-per-dish when they work. Perfect for occasional tasks.


Why Use Azure Functions?

  • Serverless: No infrastructure to manage
  • Event-driven: Trigger on HTTP, timer, queue, blob
  • Auto-scaling: Handle any load automatically
  • Pay per execution: Zero cost when idle
  • Quick deployment: Write and deploy in minutes

HTTP Trigger Function

using Azure.Functions.Worker;
using Azure.Functions.Worker.Http;

public static class OrderFunction
{
    [Function("CreateOrder")]
    public static async Task<HttpResponseData> Run(
        [HttpTrigger(AuthorizationLevel.Function, "post", Route = "orders")] 
        HttpRequestData req,
        FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger("CreateOrder");
        
        var requestBody = await new StreamReader(req.Body).ReadToEndAsync();
        var order = JsonSerializer.Deserialize<Order>(requestBody);
        
        logger.LogInformation($"Creating order for user: {order.UserId}");
        
        var response = req.CreateResponse(System.Net.HttpStatusCode.OK);
        response.Headers.Add("Content-Type", "application/json");
        await response.WriteAsJsonAsync(new { OrderId = Guid.NewGuid() });
        
        return response;
    }
}

Timer Trigger Function

[Function("ProcessExpiredSessions")]
public static void RunTimer(
    [TimerTrigger("0 */5 * * * *")] TimerInfo timerInfo,
    ILogger log)
{
    log.LogInformation($"Cleaning expired sessions at {DateTime.Now}");
    
    // Clean up expired sessions every 5 minutes
    var expiredSessions = _sessionRepository.GetExpired();
    foreach (var session in expiredSessions)
    {
        _sessionRepository.Delete(session.Id);
    }
    
    log.LogInformation($"Cleaned {expiredSessions.Count} sessions");
}

Queue Trigger Function

[Function("ProcessOrderQueue")]
public static async Task RunQueue(
    [QueueTrigger("orders")] Order order,
    [Blob("completed-orders/{Id}")] CloudBlockBlob blob,
    ILogger log)
{
    log.LogInformation($"Processing order {order.Id}");
    
    // Process the order
    var result = await _orderService.ProcessAsync(order);
    
    // Save to blob storage
    await blob.UploadTextAsync(JsonSerializer.Serialize(result));
    
    log.LogInformation($"Order {order.Id} completed");
}

Dependency Injection

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults()
    .ConfigureServices(services => 
    {
        services.AddApplicationInsightsTelemetry();
        services.AddScoped<IOrderService, OrderService>();
        services.AddScoped<IRepository, Repository>();
    })
    .Build();

host.Run();

Best Practices

  1. Keep functions small: Single responsibility
  2. Use dependencies: Inject services
  3. Handle errors: Retry and dead-letter
  4. Monitor performance: Application Insights
  5. Set timeouts: Default is 5 minutes

Related Concepts

  • Logic Apps for workflows
  • Event Grid for event routing
  • Service Bus for reliable messaging
  • Durable Functions for long-running processes

Summary

Azure Functions enable serverless computing with automatic scaling and pay-per-execution pricing. Perfect for event-driven, occasional workloads.