-
-
Notifications
You must be signed in to change notification settings - Fork 15
Open
Description
Summary
Extend the existing source generator to create type-safe extension methods for accessing each module's result, eliminating the need for developers to specify both type parameters.
Current API
// Requires knowing and specifying both types
var result = await context.GetModule<BuildModule, BuildOutput>();Proposed Generated API
For each module in the assembly, generate:
// Auto-generated in: BuildModule.Generated.cs
public static class BuildModuleExtensions
{
/// <summary>
/// Gets the result of <see cref="BuildModule"/>.
/// </summary>
public static ModuleResult<BuildOutput> GetBuildModule(this IModuleContext context)
=> context.GetModule<BuildModule, BuildOutput>();
}Usage becomes:
var result = await context.GetBuildModule();Benefits
- Type inference: No need to specify result type
- Discoverability: IntelliSense shows all available modules
- Documentation: Generated XML docs link to module type
- Compile-time safety: Can't request wrong result type
Implementation
Source Generator Addition
Extend ModularPipelines.SourceGenerator:
[Generator]
public class ModuleAccessorGenerator : ISourceGenerator
{
public void Execute(GeneratorExecutionContext context)
{
// Find all types inheriting from Module<T>
var modules = FindModuleTypes(context.Compilation);
foreach (var module in modules)
{
var resultType = GetResultType(module);
var source = GenerateAccessorExtension(module, resultType);
context.AddSource($"{module.Name}Extensions.g.cs", source);
}
}
}Generated Code Template
// <auto-generated />
using System.CodeDom.Compiler;
using ModularPipelines.Context;
using ModularPipelines.Models;
namespace {ModuleNamespace}
{
[GeneratedCode("ModularPipelines.SourceGenerator", "1.0.0")]
public static class {ModuleName}Extensions
{
/// <summary>
/// Gets the result of <see cref="{ModuleName}"/>.
/// </summary>
/// <param name="context">The module context.</param>
/// <returns>The module result containing <see cref="{ResultType}"/>.</returns>
public static ModuleResult<{ResultType}> Get{ModuleName}(this IModuleContext context)
=> context.GetModule<{ModuleName}, {ResultType}>();
}
}Naming Conventions
BuildModule→GetBuildModule()DeployToProductionModule→GetDeployToProductionModule()- Strip "Module" suffix if present:
Buildclass →GetBuild()
Considerations
- Name collisions: Multiple modules with same name in different namespaces
- Visibility: Only generate for public modules
- Partial classes: Consider generating as partial for extensibility
- Opt-out: Attribute to disable generation for specific modules
Related Issues
- [v2.0 Breaking] Simplify Module result access API - remove dual type parameters #1988 - Simplify Module result access API (this is the implementation approach)
Impact
- Non-breaking: Additive feature, old API still works
- Improves: Developer experience, type safety, discoverability
Labels
- enhancement
- source-generator
- v2.0
- developer-experience
Metadata
Metadata
Assignees
Labels
No labels