azure-functions-templates icon indicating copy to clipboard operation
azure-functions-templates copied to clipboard

Update Visual Studio templates to use "nameof" instead of hardcoded function name

Open soninaren opened this issue 6 years ago • 7 comments

Original issue posted by @Andrew-MSFT at https://github.com/Azure/Azure-Functions/issues/763

Currently the function templates hardcode the string to match the name of the class. The suggestion is to change the hardcoded string in the FunctionName attribute to be a nameof the class. This makes refactoring much cleaner since by default the function name will always match the class name.

So

public static class Function1 { [FunctionName("Function1")] public static IActionResult Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", ...

would become

public static class Function1 { [FunctionName(nameof(Function1))] public static IActionResult Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", ...

soninaren avatar Apr 16 '18 21:04 soninaren

@fabiocav thinks we started doing this at some point and stopped (can we remember why?)

paulbatum avatar Apr 18 '18 18:04 paulbatum

It drives me crazy that it doesn't use nameof by default. It's the first thing I change. Every. Time.

MisinformedDNA avatar May 31 '18 20:05 MisinformedDNA

This will be especially useful for the Durable Function template. Note that I think we should do the name of the method and not the name of the class? Specifically for durable template you have multiple functions in same class:

using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;

namespace durabledemorunthrough
{
    public static class Function1
    {
        [FunctionName(nameof(RunOrchestrator))]
        public static async Task<List<string>> RunOrchestrator(
            [OrchestrationTrigger] DurableOrchestrationContext context)
        {
            var outputs = new List<string>();

            // Replace "hello" with the name of your Durable Activity Function.
            outputs.Add(await context.CallActivityAsync<string>(nameof(SayHello), "Tokyo"));
            outputs.Add(await context.CallActivityAsync<string>(nameof(SayHello), "Seattle"));
            outputs.Add(await context.CallActivityAsync<string>(nameof(SayHello), "London"));

            // returns ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]
            return outputs;
        }

        [FunctionName(nameof(SayHello))]
        public static string SayHello([ActivityTrigger] string name, ILogger log)
        {
            log.LogInformation($"Saying hello to {name}.");
            return $"Hello {name}!";
        }

        [FunctionName(nameof(HttpStart))]
        public static async Task<HttpResponseMessage> HttpStart(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")]HttpRequestMessage req,
            [OrchestrationClient]DurableOrchestrationClient starter,
            ILogger log)
        {
            // Function input comes from the request content.
            string instanceId = await starter.StartNewAsync(nameof(RunOrchestrator), null);

            log.LogInformation($"Started orchestration with ID = '{instanceId}'.");

            return starter.CreateCheckStatusResponse(req, instanceId);
        }
    }
}

jeffhollan avatar Sep 12 '18 21:09 jeffhollan

@cgillum as FYI - I think I'm quite partial to switching docs and samples for durable to use nameof() instead. Makes renaming a bit easier and clear relationship at a compile-time level for things like CallActivityAsync and the function.

jeffhollan avatar Sep 12 '18 21:09 jeffhollan

I still can't remember why we didn't do this the first time it came up. Is it possible that there are valid C# method names that are invalid function names? That might be a reason.

paulbatum avatar Sep 13 '18 19:09 paulbatum

I recall either Mike saying this or reading a comment in the WebJobs code that function names must be valid C# identifiers. If that's the case, it seems like it would be safe to do this. But even so, if we control the templates, it seems it would be safe for us to use nameof.

I considered that maybe there was a reason related to name conflicts (e.g. if two functions had the same method name - like method overloads) but even then I think WebJobs explicitly blocks that.

cgillum avatar Sep 13 '18 20:09 cgillum

Seems like everyone is for this change, and I am here in 2023 and still changing from magic strings to nameof in Azure Functions 😛

Sti2nd avatar Jan 12 '23 12:01 Sti2nd