英文:
In C#, Can I make my Azure Function App more DRY?
问题
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("GenerateForInitialUpload")]
[SuppressMessage("Roslynator", "RCS1163:Unused parameter.", Justification = "Used for Azure Function")]
public async Task Generate(
[TimerTrigger("%InitialUpload:DirectoryScanFrequencyCron%")] TimerInfo timer,
CancellationToken cancellationToken
) =>
await _taskEventGeneratorHelper.Generate(_taskEventGeneratorConfig, cancellationToken);
}
这些类在两个方面完全相同:
- 类名。
const string _configName
的值。
_taskEventGeneratorConfig
和 $"%{_configName}:DirectoryScanFrequencyCron%"
的值都来自 appsettings 文件。
目前,每当我们想要添加一个新的配置以及新的频率时,我们需要硬编码另一个类并在 TaskEventGeneratorSettingNames
中添加常量值。
有没有办法我们可以只有一个 Generate
方法来做同样的事情?
(我在思考是否可以使用元编程从单个类生成一系列类?)
是否可能进一步包括所有配置,包括 appsettings 中的 cron 频率在数组中,然后根本不需要在任何地方硬编码配置名称值?
英文:
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:
- The class name.
- 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
得分: 1
功能应用程序需要静态定义其功能,以便主机知道需要设置的所有触发器。根据此约束,您的解决方案必须在编译时生成。Appsettings 是一个运行时解决方案。
编译时生成在 C# 中一直是一个薄弱点,但现在我们有源代码生成器。它们不难编写,并且可以基于特殊文件,例如 timedtasks.json
。
英文:
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
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论