In C#, Can I make my Azure Function App more DRY?

88 Views Asked by At

I have a Function App composed in C#.

It has a bunch of classes like:

public class InitialUploadNewOrModifiedFileTaskEventGenerator
{
    private readonly TaskEventGeneratorConfig _taskEventGeneratorConfig;
    private readonly NewOrModifiedFileTaskEventGeneratorHelper _taskEventGeneratorHelper;

    private const string _configName = TaskEventGeneratorSettingNames.InitialUpload;

    public InitialUploadNewOrModifiedFileTaskEventGenerator(
            ITaskEventGeneratorConfigFactory taskEventGeneratorConfigFactory,
            NewOrModifiedFileTaskEventGeneratorHelper taskEventGeneratorHelper
        )
    {
        _taskEventGeneratorConfig = Guard.Against.Null(taskEventGeneratorConfigFactory)
            .GetConfig(_configName);
        _taskEventGeneratorHelper = Guard.Against.Null(taskEventGeneratorHelper);
    }

    [FunctionName($"GenerateFor{_configName}")]
    [SuppressMessage("Roslynator", "RCS1163:Unused parameter.", Justification = "Used for Azure Function")]
    public async Task Generate(
        [TimerTrigger($"%{_configName}:DirectoryScanFrequencyCron%")] TimerInfo timer,
        CancellationToken cancellationToken
    ) =>
        await _taskEventGeneratorHelper.Generate(_taskEventGeneratorConfig, cancellationToken);
}

Which are identical in all but 2 things:

  1. The class name.
  2. The value of const string _configName.

The values of _taskEventGeneratorConfig and $"%{_configName}:DirectoryScanFrequencyCron%" both come from the appsettings file.

At present, each time we want to add a new configuration with a new frequency, we need to hardcode another class and add constant value in TaskEventGeneratorSettingNames.

Is there a way we can do the same thing only having one Generate method? (I'm thinking some sort of metaprogramming to generate a series of classes from a single class?)

Would it be possible to go a step further and include all the configurations, including the cron frequencies within an array in the appsettings, and then not even need to hardcode config name values anywhere?

1

There are 1 best solutions below

2
Stephen Cleary On

Functions apps need to define their functions statically, so the host knows all the triggers that need to be set up. With this constraint, your solution must be compile-time. Appsettings is a runtime solution.

Compile-time generation has historically been a weak point for C#, but these days we have source generators. They're not hard to write, and they can key off of a special file like timedtasks.json.