Best practice when naming Durable Functions in C#
Tags: serverless, azurefunctions, dotnet
Published: 2020-11-04 19:37:03

---
title: Best practice when naming Durable Functions in C#
published: true
description: Durable functions rely on "magic strings" which can be replaced with the nameto operator
tags: serverless, azurefunctions, dotnet
---
When you create a new [Durable Function in C#](http://gslb.ch/d597b), you get some code which looks like this:

``` cs
[FunctionName("Function1")]
public static async Task<List<string>> RunOrchestrator(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var outputs = new List<string>();

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

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

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

> For brevity, I didn't include the HttpStart method here, it's not relevant to this discussion.

As you can see here, the execution of the program relies on some strings. 

- The `FunctionName` attribute which decorates the function `SayHello` uses a string as the function's identifier.
- When the function is called by the `context.CallActivityAsync` method, the first argument of the method is the magic string identifying the function.

## About Magic strings

The term "Magic string" in programming refers to identifiers which are stored in a string format. They are deemed "magic" because they have a specific meaning critical to the execution of the program.

One thing I learned when I was learning programming is that in general, it's not a great idea to rely on "magic strings". They are dangerous, because a typo will not be detected by the compiler (compilers don't normally check the format of string variables). So the risk of getting problems at some point is higher.

## Using the `nameof` operator

In order to minimize the need of magic string, C# introduced the `nameof` operator.

This can be used on a number of identifiers in the code. For example you can consider this code:

```cs
public class MyClass
{
    public int MyProperty
    {
        get;
        set;
    }

    public void MyMethod()
    {
    }

    public void ShowNames()
    {
        Console.WriteLine(nameof(MyClass)); // prints "MyClass"
        Console.WriteLine(nameof(MyProperty)); // prints "MyProperty"
        Console.WriteLine(nameof(MyMethod)); // prints "MyMethod"
    }
}
```

## So what's the point?

The point of the `nameof` operator is that it makes it easier to detect typos or changes in the code. For example, if you change the name of `MyClass` to `MyNewClass`, then the code won't compile unless you also change it inside the `nameof` operator.

If you use refactoring tools, for example inside of Visual Studio, you can easily rename all the instances of the `MyClass` identifier without having to search-and-replace.

Finally, it also makes it easier to navigate the code. If you are inside the `nameof` operator, place your cursor on `MyClass` and press F12 (in Visual Studio), this will take you directly inside the `MyClass` class, even if it is located in another file.

## Next steps for Durable Functions

For Durable Functions, my first step was always to modify the code like this:

```cs
[FunctionName(nameof(Function1))]
public static async Task<List<string>> RunOrchestrator(
    [OrchestrationTrigger] IDurableOrchestrationContext 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}!";
}
```

These few changes (using `nameof`) minimize the usage of magic strings and make it easier for me to navigate the code.

## Changing the templates

In order to make this easier for everyone, I proposed [a change to the C# templates for Durable Functions](https://github.com/Azure/azure-functions-templates/pull/993) which, if accepted, should promote the usage of `nameof` in the generated code.

Happy coding!

Laurent