Azure / azure-functions-templates

Azure functions templates for the azure portal, CLI, and VS
MIT License
344 stars 196 forks source link

Consider using modern C# features for generated triggers #1577

Open captainsafia opened 1 week ago

captainsafia commented 1 week ago

Currently, instantiated new triggers with the C# isolate model will produce code like the following:

using System.IO;
using System.Threading.Tasks;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

namespace Company.Function
{
    public class BlobTriggerCSharp
    {
        private readonly ILogger<BlobTriggerCSharp> _logger;

        public BlobTriggerCSharp(ILogger<BlobTriggerCSharp> logger)
        {
            _logger = logger;
        }

        [Function(nameof(BlobTriggerCSharp))]
        public async Task Run([BlobTrigger("PathValue/{name}", Connection = "ConnectionValue")] Stream stream, string name)
        {
            using var blobStreamReader = new StreamReader(stream);
            var content = await blobStreamReader.ReadToEndAsync();
            _logger.LogInformation($"C# Blob trigger function Processed blob\n Name: {name} \n Data: {content}");
        }
    }
}

If possible, this code would benefit from using the new primary constructors feature in C# 12:

using System.IO;
using System.Threading.Tasks;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

namespace Company.Function
{
    public class BlobTriggerCSharp(ILogger<BlobTriggerCSharp> logger)
    {
        [Function(nameof(BlobTriggerCSharp))]
        public async Task Run([BlobTrigger("PathValue/{name}", Connection = "ConnectionValue")] Stream stream, string name)
        {
            using var blobStreamReader = new StreamReader(stream);
            var content = await blobStreamReader.ReadToEndAsync();
            logger.LogInformation($"C# Blob trigger function Processed blob\n Name: {name} \n Data: {content}");
        }
    }
}

We could potentially reduce more nesting and code by using file-scoped namespaces as well to further reduce it to:

using System.IO;
using System.Threading.Tasks;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

namespace Company.Function;

public class BlobTriggerCSharp(ILogger<BlobTriggerCSharp> logger)
{
    [Function(nameof(BlobTriggerCSharp))]
    public async Task Run([BlobTrigger("PathValue/{name}", Connection = "ConnectionValue")] Stream stream, string name)
    {
        using var blobStreamReader = new StreamReader(stream);
        var content = await blobStreamReader.ReadToEndAsync();
        logger.LogInformation($"C# Blob trigger function Processed blob\n Name: {name} \n Data: {content}");
    }
}
captainsafia commented 1 week ago

Edit: We can further reduce the amount of code in the generated template by using global using to get rid of the using statements at the top.