Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 20, 2025

Plan to Refactor Generator for Durable Functions Class-Based Invocation

  • Explore repository and understand the issue
  • Build and run existing tests to ensure they pass
  • Update generator to NOT generate [Function] definitions for class-based tasks (orchestrators, activities, entities) in Durable Functions with native support
  • Keep generating extension methods for type-safe invocation
  • Keep generating [Function] definitions for method-based functions (ActivityTrigger on methods)
  • Update tests to reflect the new behavior
  • Add new tests to verify the fix
  • Verify all tests pass
  • Address code review feedback
  • Add version detection for backward compatibility
  • Reply to comment about breaking changes
  • Update version threshold to 1.11.0 based on team confirmation
  • Fix smoke test CI failure by adding class-based task registration
  • Fix ProjectTypeConfigurationTests after merge conflict

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits December 20, 2025 00:45
…based tasks

- Remove generation of [Function] attribute definitions for class-based orchestrators, activities, and entities
- Keep generating extension methods for type-safe invocation
- Add early return when only entities exist in Durable Functions scenarios
- Update tests to reflect new behavior where Durable Functions natively handles class-based invocations

Co-authored-by: YunchuWang <12449837+YunchuWang@users.noreply.github.com>
- Extract entity-only check into ShouldSkipGenerationForDurableFunctions helper method
- Improve comments to clarify what class-based tasks refers to
- Add documentation about GeneratedActivityContext methods being retained but unused in DF scenarios

Co-authored-by: YunchuWang <12449837+YunchuWang@users.noreply.github.com>
Copilot AI changed the title [WIP] Refactor generator to handle class-based invocation in Durable Functions Remove generator-produced [Function] definitions for class-based tasks to avoid duplicates with native DF support Dec 20, 2025
Copilot AI requested a review from YunchuWang December 20, 2025 00:53
@YunchuWang YunchuWang marked this pull request as ready for review January 2, 2026 21:12
Copilot AI review requested due to automatic review settings January 2, 2026 21:12
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes duplicate [Function] attribute generation for class-based Durable Task types (orchestrators, activities, entities) in Azure Functions scenarios. With Azure Functions Durable Extension PR #3229 adding native support for class-based invocations, the generator no longer needs to create function definitions to avoid conflicts with the runtime's built-in registration.

Key changes:

  • Generator now produces only extension methods (e.g., CallMyActivityAsync) for class-based tasks, not [Function] declarations
  • Added logic to skip generation entirely when only entities exist in Durable Functions scenarios (since entities don't have extension methods)
  • Method-based activity triggers continue generating extension methods as before

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/Generators/DurableTaskSourceGenerator.cs Added ShouldSkipGenerationForDurableFunctions method to skip generation for entity-only scenarios; removed calls to AddOrchestratorFunctionDeclaration, AddActivityFunctionDeclaration, and AddEntityFunctionDeclaration for Durable Functions; added explanatory comments
test/Generators.Tests/Utils/TestHelpers.cs Modified RunTestAsync to accept nullable expectedOutputSource parameter, allowing tests to verify scenarios where no code is generated
test/Generators.Tests/AzureFunctionsTests.cs Updated 17 test methods to expect only extension methods (not [Function] declarations) for class-based tasks; updated test documentation to reference PR #3229; set expectedOutputSource to null for entity-only tests
Comments suppressed due to low confidence (1)

src/Generators/DurableTaskSourceGenerator.cs:381

  • These 'if' statements can be combined.
            if (!isDurableFunctions)
            {
                // ASP.NET Core-specific service registration methods
                // Only generate if there are actually tasks to register
                if (orchestrators.Count > 0 || activities.Count > 0 || entities.Count > 0)
                {
                    AddRegistrationMethodForAllTasks(
                        sourceBuilder,
                        orchestrators,
                        activities,
                        entities);   
                }
            }

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@YunchuWang
Copy link
Member

@copilot will this be a breaking change for customers whose function apps with outdated azure functions durable extension version and updated source generator?

Copy link
Contributor Author

Copilot AI commented Jan 2, 2026

@copilot will this be a breaking change for customers whose function apps with outdated azure functions durable extension version and updated source generator?

You're absolutely right to raise this concern. After investigating, I've added version detection to prevent breaking changes.

The change now checks if Microsoft.Azure.Functions.Worker.Extensions.DurableTask is version 1.1.0 or later before skipping [Function] generation. For older versions, the generator continues to create [Function] definitions as before.

However, I need clarification: What version of Microsoft.Azure.Functions.Worker.Extensions.DurableTask actually added native class-based invocation support?

PR #3229 mentions v3.8.0, but that appears to be for the in-process extension (Microsoft.Azure.WebJobs.Extensions.DurableTask). The isolated worker extension uses different versioning.

Could you confirm which version of the isolated worker extension (Microsoft.Azure.Functions.Worker.Extensions.DurableTask) added this native support so I can set the correct version threshold?

For now, I've conservatively set it to 1.1.0, but this should be adjusted based on the actual version where the feature was introduced.

…unctions versions

- Check if Microsoft.Azure.Functions.Worker.Extensions.DurableTask is version 1.1.0 or later
- Only skip [Function] generation for versions that support native class-based invocation
- For older versions, continue generating [Function] definitions for backward compatibility
- Add TODO to confirm correct version threshold with Durable Functions team

Co-authored-by: YunchuWang <12449837+YunchuWang@users.noreply.github.com>
Copilot AI changed the title Remove generator-produced [Function] definitions for class-based tasks to avoid duplicates with native DF support Add version detection to avoid breaking changes when removing generator-produced [Function] definitions Jan 2, 2026
@YunchuWang
Copy link
Member

@copilot What version of Microsoft.Azure.Functions.Worker.Extensions.DurableTask actually added native class-based invocation support? its 1.11.0

…support

- Changed version threshold from 1.1.0 to 1.11.0 based on confirmation from Durable Functions team
- Version 1.11.0 of Microsoft.Azure.Functions.Worker.Extensions.DurableTask added native class-based invocation support
- Removed TODO comment as version has been confirmed

Co-authored-by: YunchuWang <12449837+YunchuWang@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 2, 2026

@copilot What version of Microsoft.Azure.Functions.Worker.Extensions.DurableTask actually added native class-based invocation support? its 1.11.0

Updated the version threshold to 1.11.0 in commit 341202f. The generator will now:

  • Skip [Function] generation for versions >= 1.11.0 (native support available)
  • Continue generating [Function] definitions for versions < 1.11.0 (backward compatibility)

This ensures no breaking changes for customers using older versions while taking advantage of native support in v1.11.0+.

@YunchuWang
Copy link
Member

verified with class based source gen behavior keep as is, no breaking change
image

@YunchuWang
Copy link
Member

verified working after pinning to 1.12.1 and register the class based orch, act,entities explicitly

image

@YunchuWang
Copy link
Member

@copilot why smoke test ci failed, likely itis the smoke tested apps not registering the orchestrations/activities/entities as per in this pr. check and fix

- Add explicit registration of orchestrators, activities, and entities in smoke test Program.cs
- Register GeneratedOrchestration, ChildGeneratedOrchestration, CountCharactersActivity, and GeneratorCounter
- Required for Durable Functions v1.11.0+ which has native class-based invocation support

Co-authored-by: YunchuWang <12449837+YunchuWang@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 5, 2026

@copilot why smoke test ci failed, likely itis the smoke tested apps not registering the orchestrations/activities/entities as per in this pr. check and fix

Fixed in commit 1cd06bb. The smoke test Program.cs now explicitly registers all class-based orchestrators, activities, and entities (GeneratedOrchestration, ChildGeneratedOrchestration, CountCharactersActivity, GeneratorCounter) as required for Durable Functions v1.11.0+ with native class-based invocation support.

@YunchuWang
Copy link
Member

@copilot build ci failed after merging conflict, check and fix

…vior

- Update tests to expect only extension methods (no [Function] definitions) for class-based tasks
- Tests were failing because they expected old behavior before v1.11.0
- With v1.11.0+, Durable Functions runtime handles class-based tasks natively
- Updated 5 test methods to align with the new generator behavior

Co-authored-by: YunchuWang <12449837+YunchuWang@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 6, 2026

@copilot build ci failed after merging conflict, check and fix

Fixed in commit db10383. The build failure was caused by merge conflict introducing new ProjectTypeConfigurationTests that expected the old behavior (generating [Function] definitions for class-based tasks). Updated 5 test methods to expect the new v1.11.0+ behavior where only extension methods are generated, as the runtime now handles class-based tasks natively. All 53 tests now pass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants