Azure / azure-functions-dotnet-worker

Azure Functions out-of-process .NET language worker
MIT License
431 stars 184 forks source link

Inheriting FunctionAttribute not supported? #2528

Open eholman opened 5 months ago

eholman commented 5 months ago

I'm trying to inherit the FunctionAttribute but it's not working like I expect it would..

Is this something that isn't supported or am I missing something?

This is my attribute:

[AttributeUsage(AttributeTargets.Method, Inherited = false)]
public class WorkflowAttribute(string name) : FunctionAttribute(name)
{
    private Type[] _triggers = [];

    public Type[] Triggers
    {
        get => _triggers;
        set
        {
            if (value.Any(t => !typeof(IWorkflowTrigger).IsAssignableFrom(t)))
            {
                throw new ArgumentException("All types must implement IWorkflowTrigger interface");
            }
            _triggers = value;
        }
    }

    public string? Description { get; set; }
}

Implementation should just be as simple as replacing the Function attribute:

    [Workflow(nameof(StartSalesOrderWorkflowsAsync), Triggers = [typeof(SalesOrderCompletedMessage)])]
    public static async Task<bool> StartSalesOrderWorkflowsAsync(
        [OrchestrationTrigger] TaskOrchestrationContext context, ...

It doesn't matter where the custom attribute resides, same assembly or not.

jviau commented 5 months ago

@eholman can you share your use case for inheriting this attribute, and what "not working like I expect it would" entails?

For context, inheritance of this attribute is not a goal nor supported scenario of ours. Many features rely on finding it by name and most likely do not consider inheritance. Adding support for this is most likely not a priority of ours either - but if you share context, we can have an internal discussion regarding the scenario.

eholman commented 5 months ago

@jviau my use case is that I'm creating a workflow based on functions (orchestrations).

I'm sending messages to an azure service bus and when that message implements the IWorkflowTrigger marker interface the message is forwarded to an generic workflow topic.

I would like to define which workflow can be triggered by specific messages, so I thought to put that in an attribute which inherits Function - in my case it'll always be a function - and just decorate the static method with just one attribute 🙂

The function app has a subscription to the SB topic so it could schedule an orchestration. Based on conditions, multiple orchestrations can be started, linked via the trigger.

I hope I've explained it well enough.

My expectation was, because inheritance is allowed by the attribute, that the function would still be discovered.

jviau commented 5 months ago

Understood - we can discuss in the team if we want to support function discovery from derived attributes.

As for workflows, are you familiar with durable functions? Which is an existing workflow/orchestration system: https://learn.microsoft.com/azure/azure-functions/durable/

eholman commented 5 months ago

Okay. When it's not possible to support (yet), maybe set inherit to false? It took me a bit of time to conclude that i wasn't doing something wrong...

Yes, I'm using durable functions with SQL server as storage provider.