diff --git a/Directory.Build.props b/Directory.Build.props index 78b44622..f997959f 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,6 +1,6 @@ - 2.0.0-beta.7 + 2.0.0-beta.8 MIT diff --git a/README.md b/README.md index 57801514..2afe9c9b 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ builder.Services.AddScoped(); var lambda = builder.Build(); // Inject the service directly into the handler -lambda.MapHandler(([Event] string input, IGreetingService greeting) => greeting.Greet(input)); +lambda.MapHandler(([FromEvent] string input, IGreetingService greeting) => greeting.Greet(input)); await lambda.RunAsync(); diff --git a/docs/features/envelopes.md b/docs/features/envelopes.md index 384a01b6..31ae1887 100644 --- a/docs/features/envelopes.md +++ b/docs/features/envelopes.md @@ -62,7 +62,7 @@ var builder = LambdaApplication.CreateBuilder(); var lambda = builder.Build(); lambda.MapHandler( - ([Event] SqsEnvelope envelope, ILogger logger) => + ([FromEvent] SqsEnvelope envelope, ILogger logger) => { foreach (var record in envelope.Records) { @@ -90,7 +90,7 @@ different success and error response types. ```csharp title="API Gateway Example" linenums="1" using MinimalLambda.Envelopes.ApiGateway; -lambda.MapHandler(([Event] ApiGatewayRequestEnvelope request) => +lambda.MapHandler(([FromEvent] ApiGatewayRequestEnvelope request) => { // Each return statement uses a different strongly typed model if (string.IsNullOrEmpty(request.BodyContent?.Username)) @@ -273,7 +273,7 @@ public sealed class CustomRequestEnvelope : IRequestEnvelope In a handler: ```csharp title="Program.cs" linenums="1" -lambda.MapHandler(([Event] CustomRequestEnvelope envelope) => +lambda.MapHandler(([FromEvent] CustomRequestEnvelope envelope) => { if (envelope.PayloadContent is null) return new { Error = "Invalid payload" }; diff --git a/docs/features/open_telemetry.md b/docs/features/open_telemetry.md index 540d93f0..64bbbac7 100644 --- a/docs/features/open_telemetry.md +++ b/docs/features/open_telemetry.md @@ -76,7 +76,7 @@ lambda.UseOpenTelemetryTracing();// (7)! lambda.OnShutdownFlushOpenTelemetry();// (8)! lambda.MapHandler(// (9)! - async ([Event] Request request, ILogger logger, CancellationToken cancellationToken) => + async ([FromEvent] Request request, ILogger logger, CancellationToken cancellationToken) => { logger.LogInformation("Responding to {Name}", request.Name); @@ -290,7 +290,7 @@ namespace MinimalLambda.Example.OpenTelemetry; internal static class Function { internal static async Task Handler( - [Event] Request request, + [FromEvent] Request request, IService service, Instrumentation instrumentation, CancellationToken cancellationToken diff --git a/docs/getting-started/core-concepts.md b/docs/getting-started/core-concepts.md index d03d2d4a..25998bd2 100644 --- a/docs/getting-started/core-concepts.md +++ b/docs/getting-started/core-concepts.md @@ -48,7 +48,7 @@ Every event runs through the middleware pipeline and handler you registered with **Invocation steps:** 1. Lambda runtime delivers the JSON payload. -2. The generated handler deserializes it (if you marked a parameter with `[Event]`). +2. The generated handler deserializes it (if you marked a parameter with `[FromEvent]`). 3. `MinimalLambda` creates a scoped `IServiceProvider` for the invocation. 4. Middleware executes in the order it was registered. 5. Your handler runs and can resolve services/contexts from DI. @@ -132,7 +132,7 @@ Every middleware component and handler can ask for `ILambdaHostContext`. Think o ```csharp title="Program.cs" linenums="1" lambda.MapHandler(async ( - [Event] OrderRequest request, + [FromEvent] OrderRequest request, ILambdaHostContext context, IOrderService service, CancellationToken ct @@ -151,7 +151,7 @@ lambda.MapHandler(async ( Handlers and lifecycle hooks can request multiple parameter types simultaneously: -- `[Event] T event` – Optional marker for the deserialized payload. Include it only when your Lambda expects input; the generator enforces that at most one parameter carries `[Event]`. +- `[FromEvent] T event` – Optional marker for the deserialized payload. Include it only when your Lambda expects input; the generator enforces that at most one parameter carries `[FromEvent]`. - Services – Any registered service, keyed service (`[FromKeyedServices("key")]`), or options type. - Context – `ILambdaHostContext` or the raw `ILambdaContext` from the AWS SDK. - `CancellationToken` – Linked to end-to-end timeouts; pass it downstream. @@ -176,7 +176,7 @@ lambda.UseMiddleware(async (context, next) => await next(context); }); -lambda.MapHandler(([Event] OrderRequest order) => new OrderResponse(order.Id, true)); +lambda.MapHandler(([FromEvent] OrderRequest order) => new OrderResponse(order.Id, true)); ``` **Ordering guidance:** diff --git a/docs/getting-started/first-lambda.md b/docs/getting-started/first-lambda.md index edf362e8..68f058ac 100644 --- a/docs/getting-started/first-lambda.md +++ b/docs/getting-started/first-lambda.md @@ -155,12 +155,12 @@ lambda.UseMiddleware( ## Step 6: Register the Handler -Map your handler function with the `[Event]` attribute to mark the Lambda event parameter. +Map your handler function with the `[FromEvent]` attribute to mark the Lambda event parameter. ```csharp title="Program.cs (continued)" // Register the handler with dependency injection lambda.MapHandler( - ([Event] GreetingRequest request, IGreetingService service) => + ([FromEvent] GreetingRequest request, IGreetingService service) => { var message = service.GetGreeting(request.Name, request.Language); return new GreetingResponse(message, DateTime.UtcNow); @@ -168,8 +168,8 @@ lambda.MapHandler( ); ``` -!!! warning "The [Event] Attribute" - Add `[Event]` to at most one handler parameter to mark it as the deserialized Lambda event. If your handler does not accept an event payload (e.g., scheduled invocations or DI-only inputs), you can omit the attribute entirely. +!!! warning "The [FromEvent] Attribute" + Add `[FromEvent]` to at most one handler parameter to mark it as the deserialized Lambda event. If your handler does not accept an event payload (e.g., scheduled invocations or DI-only inputs), you can omit the attribute entirely. ## Step 7: Run the Lambda @@ -219,7 +219,7 @@ lambda.UseMiddleware( // Handler lambda.MapHandler( - ([Event] GreetingRequest request, IGreetingService service) => + ([FromEvent] GreetingRequest request, IGreetingService service) => { var message = service.GetGreeting(request.Name, request.Language); return new GreetingResponse(message, DateTime.UtcNow); @@ -569,9 +569,9 @@ sequenceDiagram **Solution**: Verify you've added `[property: JsonPropertyName("...")]` attributes to your record properties. -### Build Errors with [Event] Attribute +### Build Errors with [FromEvent] Attribute -**Error**: `The [Event] attribute is not recognized` +**Error**: `The [FromEvent] attribute is not recognized` **Solution**: Add `using MinimalLambda.Builder;` to the top of your file (or fully qualify `[MinimalLambda.Builder.Event]`). The attribute ships with the `MinimalLambda` package—no additional project configuration is required. @@ -598,7 +598,7 @@ Congratulations! You've built and deployed a complete Lambda function. You now u - ✅ Defining strongly-typed request/response models - ✅ Creating and registering services with dependency injection - ✅ Adding middleware for cross-cutting concerns -- ✅ Using the `[Event]` attribute for handler parameters +- ✅ Using the `[FromEvent]` attribute for handler parameters - ✅ Testing locally with the Lambda Test Tool - ✅ Deploying to AWS with SAM, CDK, or manual methods diff --git a/docs/getting-started/installation.md b/docs/getting-started/installation.md index 3cfb7288..3d873889 100644 --- a/docs/getting-started/installation.md +++ b/docs/getting-started/installation.md @@ -140,7 +140,7 @@ using MinimalLambda; var builder = LambdaApplication.CreateBuilder(); var lambda = builder.Build(); -lambda.MapHandler(([Event] string input) => input.ToUpper()); +lambda.MapHandler(([FromEvent] string input) => input.ToUpper()); await lambda.RunAsync(); ``` diff --git a/docs/guides/configuration.md b/docs/guides/configuration.md index 0810f2a5..7a1db5be 100644 --- a/docs/guides/configuration.md +++ b/docs/guides/configuration.md @@ -145,7 +145,7 @@ builder.Services.ConfigureLambdaHostOptions(options => options.InvocationCancellationBuffer = TimeSpan.FromSeconds(5); }); -lambda.MapHandler(async ([Event] Order order, IOrderService service, CancellationToken ct) => +lambda.MapHandler(async ([FromEvent] Order order, IOrderService service, CancellationToken ct) => await service.ProcessAsync(order, ct)); ``` diff --git a/docs/guides/dependency-injection.md b/docs/guides/dependency-injection.md index 6723fdc8..0366fa98 100644 --- a/docs/guides/dependency-injection.md +++ b/docs/guides/dependency-injection.md @@ -46,7 +46,7 @@ across middleware and handlers: ```csharp title="Handlers" lambda.MapHandler(async ( - [Event] OrderRequest request, + [FromEvent] OrderRequest request, IOrderService orders, // scoped service ILambdaHostContext context, // framework context CancellationToken cancellation // host-managed token @@ -65,7 +65,7 @@ lambda.MapHandler(async ( - `Properties` – cross-invocation storage backed by the singleton container - `Features` – typed feature collections (advanced scenarios) -If your handler doesn't need the Lambda payload, omit the `[Event]` parameter entirely and inject only services. +If your handler doesn't need the Lambda payload, omit the `[FromEvent]` parameter entirely and inject only services. !!! tip "Cancellation buffers" The cancellation token fires slightly **before** AWS kills the process: @@ -119,7 +119,7 @@ builder.Services.AddKeyedSingleton("email"); builder.Services.AddKeyedSingleton("sms"); lambda.MapHandler(( - [Event] Order order, + [FromEvent] Order order, [FromKeyedServices("sms")] INotifier notifier ) => notifier.NotifyAsync(order)); ``` diff --git a/docs/guides/error-handling.md b/docs/guides/error-handling.md index bb44acfc..9832e25a 100644 --- a/docs/guides/error-handling.md +++ b/docs/guides/error-handling.md @@ -15,7 +15,7 @@ hooks so you can add the right amount of protection without fighting the framewo want different logging, metrics, or response shaping. ```csharp title="Program.cs" linenums="1" -lambda.MapHandler(([Event] OrderRequest request, IOrderService service) => +lambda.MapHandler(([FromEvent] OrderRequest request, IOrderService service) => service.ProcessAsync(request) // unhandled exception flows to Lambda runtime ); ``` @@ -63,7 +63,7 @@ Keep handlers thin, but do catch exceptions when you want a different payload or logic. Leave everything else to your middleware/global policy. ```csharp title="Program.cs" linenums="1" -lambda.MapHandler(async ([Event] CheckoutRequest request, ICheckoutService service) => +lambda.MapHandler(async ([FromEvent] CheckoutRequest request, ICheckoutService service) => { try { diff --git a/docs/guides/handler-registration.md b/docs/guides/handler-registration.md index f590a6bb..b0b84a1c 100644 --- a/docs/guides/handler-registration.md +++ b/docs/guides/handler-registration.md @@ -14,7 +14,7 @@ builder.Services.AddScoped(); var lambda = builder.Build(); -lambda.MapHandler(([Event] string name, IGreetingService greetings) => +lambda.MapHandler(([FromEvent] string name, IGreetingService greetings) => greetings.Greet(name) ); @@ -55,7 +55,7 @@ public static class OrderHandlers { public static void MapOrderHandler(this ILambdaInvocationBuilder app) { - app.MapHandler(([Event] OrderRequest req, IOrderService orders) => + app.MapHandler(([FromEvent] OrderRequest req, IOrderService orders) => orders.ProcessAsync(req) ); } @@ -82,13 +82,13 @@ await lambda.RunAsync(); - Feature providers are registered when `MapHandler` is called, so ensure the registered handler matches your expected event/response types - This pattern is designed for **conditional registration**, not for handling multiple event types in a single Lambda (which requires a custom routing solution) -## Handler Signatures and the `[Event]` Parameter +## Handler Signatures and the `[FromEvent]` Parameter -Handlers that receive an incoming payload must identify exactly one parameter with `[Event]`. The generator uses that marker to synthesize deserialization logic (JSON by default, or whatever envelope/serializer is active). If your Lambda does **not** expect input (e.g., scheduled jobs, health checks, etc.), you can omit the `[Event]` attribute entirely—just define a handler with no payload parameter and `MinimalLambda` skips the event binding phase. +Handlers that receive an incoming payload must identify exactly one parameter with `[FromEvent]`. The generator uses that marker to synthesize deserialization logic (JSON by default, or whatever envelope/serializer is active). If your Lambda does **not** expect input (e.g., scheduled jobs, health checks, etc.), you can omit the `[FromEvent]` attribute entirely—just define a handler with no payload parameter and `MinimalLambda` skips the event binding phase. -- `[Event]` may appear on reference types, structs, records, collection types, or envelope types such as `ApiGatewayRequestEnvelope`. -- Handlers without payloads can simply omit `[Event]` by not declaring an event parameter at all. -- When you do accept a payload, exactly one parameter must be annotated. Missing or duplicate `[Event]` attributes trigger compile-time diagnostics so you catch signature issues early. +- `[FromEvent]` may appear on reference types, structs, records, collection types, or envelope types such as `ApiGatewayRequestEnvelope`. +- Handlers without payloads can simply omit `[FromEvent]` by not declaring an event parameter at all. +- When you do accept a payload, exactly one parameter must be annotated. Missing or duplicate `[FromEvent]` attributes trigger compile-time diagnostics so you catch signature issues early. ```csharp title="Program.cs" linenums="1" // No incoming event required @@ -104,7 +104,7 @@ Handlers can mix lambda events with services, context objects, and cancellation | Parameter | Source | |--------------------------------------------------|-----------------------------------------------------------------------------------------------------| -| `[Event] T event` | Deserialized from the Lambda payload (or envelope). Optional—only include when the handler expects an input. | +| `[FromEvent] T event` | Deserialized from the Lambda payload (or envelope). Optional—only include when the handler expects an input. | | `IServiceType service` | Resolved from the DI container using the invocation scope. | | `[FromKeyedServices("key")] IServiceType keyed` | Resolves a keyed service registered with `AddKeyed*`. Keys must be constants supported by the BCL. | | `ILambdaHostContext context` | Framework context that extends `ILambdaContext`, exposes scoped `ServiceProvider`, `Items`, `Features`, `Properties`, and the invocation `CancellationToken`. | @@ -113,7 +113,7 @@ Handlers can mix lambda events with services, context objects, and cancellation ```csharp title="Program.cs" linenums="1" lambda.MapHandler(async ( - [Event] OrderRequest request, + [FromEvent] OrderRequest request, [FromKeyedServices("primary")] IOrderProcessor orderProcessor, ILambdaHostContext context, CancellationToken ct @@ -146,7 +146,7 @@ Each invocation receives its own dependency injection scope and `ILambdaHostCont ```csharp title="Program.cs" linenums="1" lambda.MapHandler(async ( - [Event] ApiGatewayRequestEnvelope request, + [FromEvent] ApiGatewayRequestEnvelope request, ILambdaHostContext context, ILogger logger, CancellationToken ct @@ -178,7 +178,7 @@ lambda.MapHandler(async ( `MapHandler` is decorated as a C# 12 interceptor target. During compilation the generator: 1. Ensures the project is built with C# 11+ so interceptors are available (otherwise `LH0004`). -2. When a payload parameter exists, verifies exactly one `[Event]` annotation is present. +2. When a payload parameter exists, verifies exactly one `[FromEvent]` annotation is present. 3. Validates keyed service metadata so the requested key matches the DI container's capabilities (`LH0003` when the key uses an unsupported type such as arrays). 4. Emits a strongly typed `Handle` call that deserializes the payload (if any), resolves services via generated code, sets up features, and serializes the response. @@ -211,7 +211,7 @@ At runtime: static class Handlers { public static async Task HandleAsync( - [Event] Request request, + [FromEvent] Request request, IService service, CancellationToken ct ) @@ -223,9 +223,9 @@ At runtime: ## Troubleshooting -**`LH0002: No parameter marked with [Event]`** +**`LH0002: No parameter marked with [FromEvent]`** -Add a `[Event]` attribute when your handler accepts an input payload. This diagnostic does **not** appear for payload-less handlers because no event parameter is required in that case. +Add a `[FromEvent]` attribute when your handler accepts an input payload. This diagnostic does **not** appear for payload-less handlers because no event parameter is required in that case. **`InvalidOperationException: No service for type ... has been registered`** diff --git a/docs/guides/hosting.md b/docs/guides/hosting.md index ed45f216..81ebb574 100644 --- a/docs/guides/hosting.md +++ b/docs/guides/hosting.md @@ -26,7 +26,7 @@ builder.Services.AddSingleton(); var lambda = builder.Build(); -lambda.MapHandler(([Event] string name, IGreetingService service) => +lambda.MapHandler(([FromEvent] string name, IGreetingService service) => service.Greet(name) ); diff --git a/docs/guides/index.md b/docs/guides/index.md index bb16e9fa..b3d3566f 100644 --- a/docs/guides/index.md +++ b/docs/guides/index.md @@ -45,7 +45,7 @@ Register type-safe Lambda handlers with automatic dependency injection and sourc **Topics covered:** - MapHandler method usage -- `[Event]` attribute requirements +- `[FromEvent]` attribute requirements - Injectable parameter types - Return type handling - Source generation benefits diff --git a/docs/guides/lifecycle-management.md b/docs/guides/lifecycle-management.md index f8bdaefe..719bb10a 100644 --- a/docs/guides/lifecycle-management.md +++ b/docs/guides/lifecycle-management.md @@ -37,7 +37,7 @@ lambda.OnInit(async (IDistributedCache cache, ILogger logger, Cancellat return true; // Keep hosting if every handler returns true }); -lambda.MapHandler(([Event] Request request) => new Response("OK")); +lambda.MapHandler(([FromEvent] Request request) => new Response("OK")); await lambda.RunAsync(); ``` diff --git a/docs/guides/middleware.md b/docs/guides/middleware.md index 8225be65..8cad67d6 100644 --- a/docs/guides/middleware.md +++ b/docs/guides/middleware.md @@ -29,7 +29,7 @@ lambda.UseMiddleware(async (context, next) => Console.WriteLine("[Metrics] After handler"); }); -lambda.MapHandler(([Event] Request request) => new Response("ok")); +lambda.MapHandler(([FromEvent] Request request) => new Response("ok")); await lambda.RunAsync(); ``` diff --git a/docs/index.md b/docs/index.md index a566c3ef..b75d6f34 100644 --- a/docs/index.md +++ b/docs/index.md @@ -85,7 +85,7 @@ already know, while still embracing Lambda’s execution model. lambda.MapHandler( async ( // ✅ Automatic envelope deserialization with strong typing - [Event] ApiGatewayRequestEnvelope request, + [FromEvent] ApiGatewayRequestEnvelope request, // ✅ Automatic DI injection - proper scoped lifetime per invocation IGreetingService service, // ✅ Automatic cancellation token - framework manages timeout @@ -168,7 +168,7 @@ using MinimalLambda.Builder; var builder = LambdaApplication.CreateBuilder(); var lambda = builder.Build(); -lambda.MapHandler(([Event] string name) => $"Hello {name}!"); +lambda.MapHandler(([FromEvent] string name) => $"Hello {name}!"); await lambda.RunAsync(); ``` diff --git a/examples/MinimalLambda.Example.Events/Program.cs b/examples/MinimalLambda.Example.Events/Program.cs index 61199221..e93caced 100644 --- a/examples/MinimalLambda.Example.Events/Program.cs +++ b/examples/MinimalLambda.Example.Events/Program.cs @@ -26,7 +26,7 @@ var lambda = builder.Build(); lambda.MapHandler( - ([Event] ApiGatewayRequestEnvelope request, ILogger logger) => + ([FromEvent] ApiGatewayRequestEnvelope request, ILogger logger) => { logger.LogInformation("In Handler. Payload: {Payload}", request.Body); diff --git a/examples/MinimalLambda.Example.HelloWorld/Program.cs b/examples/MinimalLambda.Example.HelloWorld/Program.cs index fb355c6b..2200e8d7 100644 --- a/examples/MinimalLambda.Example.HelloWorld/Program.cs +++ b/examples/MinimalLambda.Example.HelloWorld/Program.cs @@ -10,7 +10,7 @@ // Map your handler - the event is automatically injected lambda.MapHandler( - ([Event] Request request) => new Response($"Hello {request.Name}!", DateTime.UtcNow) + ([FromEvent] Request request) => new Response($"Hello {request.Name}!", DateTime.UtcNow) ); // Run the Lambda diff --git a/examples/MinimalLambda.Example.HelloWorldAot/Program.cs b/examples/MinimalLambda.Example.HelloWorldAot/Program.cs index 3cee8ebc..d3eabb0a 100644 --- a/examples/MinimalLambda.Example.HelloWorldAot/Program.cs +++ b/examples/MinimalLambda.Example.HelloWorldAot/Program.cs @@ -31,7 +31,7 @@ ); lambda.MapHandler( - ([Event] string input) => + ([FromEvent] string input) => { Console.WriteLine("hello world from aot"); return "hello world from aot"; diff --git a/examples/MinimalLambda.Example.OpenTelemetry/Function.cs b/examples/MinimalLambda.Example.OpenTelemetry/Function.cs index 0b67d6a7..29e38258 100644 --- a/examples/MinimalLambda.Example.OpenTelemetry/Function.cs +++ b/examples/MinimalLambda.Example.OpenTelemetry/Function.cs @@ -5,7 +5,7 @@ namespace MinimalLambda.Example.OpenTelemetry; internal static class Function { internal static async Task Handler( - [Event] Request request, + [FromEvent] Request request, IService service, Instrumentation instrumentation, CancellationToken cancellationToken diff --git a/src/Envelopes/MinimalLambda.Envelopes.Alb/README.md b/src/Envelopes/MinimalLambda.Envelopes.Alb/README.md index 559c213d..2aa6b673 100644 --- a/src/Envelopes/MinimalLambda.Envelopes.Alb/README.md +++ b/src/Envelopes/MinimalLambda.Envelopes.Alb/README.md @@ -40,7 +40,7 @@ var lambda = builder.Build(); // AlbRequestEnvelope provides the ALB event with deserialized request body // AlbResponseEnvelope wraps the response and serializes it to the body lambda.MapHandler( - ([Event] AlbRequestEnvelope request, ILogger logger) => + ([FromEvent] AlbRequestEnvelope request, ILogger logger) => { logger.LogInformation("Request: {Name}", request.BodyContent?.Name); @@ -68,7 +68,7 @@ multiple strongly typed models from the same handler (e.g., success vs. error re different types). ```csharp -lambda.MapHandler(([Event] AlbRequestEnvelope request) => +lambda.MapHandler(([FromEvent] AlbRequestEnvelope request) => { if (string.IsNullOrEmpty(request.BodyContent?.Name)) return AlbResult.BadRequest(new ErrorResponse("Name is required")); diff --git a/src/Envelopes/MinimalLambda.Envelopes.ApiGateway/README.md b/src/Envelopes/MinimalLambda.Envelopes.ApiGateway/README.md index 33a3a71c..68ea5f23 100644 --- a/src/Envelopes/MinimalLambda.Envelopes.ApiGateway/README.md +++ b/src/Envelopes/MinimalLambda.Envelopes.ApiGateway/README.md @@ -42,7 +42,7 @@ var lambda = builder.Build(); // ApiGatewayRequestEnvelope provides the API Gateway event with deserialized request body // ApiGatewayResponseEnvelope wraps the response and serializes it to the body lambda.MapHandler( - ([Event] ApiGatewayRequestEnvelope request, ILogger logger) => + ([FromEvent] ApiGatewayRequestEnvelope request, ILogger logger) => { logger.LogInformation("Request: {Name}", request.BodyContent?.Name); @@ -74,7 +74,7 @@ success vs. error responses with different types). ```csharp // REST API / HTTP API v1 / WebSocket -lambda.MapHandler(([Event] ApiGatewayRequestEnvelope request) => +lambda.MapHandler(([FromEvent] ApiGatewayRequestEnvelope request) => { if (string.IsNullOrEmpty(request.BodyContent?.Name)) return ApiGatewayResult.BadRequest(new ErrorResponse("Name is required")); @@ -83,7 +83,7 @@ lambda.MapHandler(([Event] ApiGatewayRequestEnvelope request) => }); // HTTP API v2 -lambda.MapHandler(([Event] ApiGatewayV2RequestEnvelope request) => +lambda.MapHandler(([FromEvent] ApiGatewayV2RequestEnvelope request) => { if (string.IsNullOrEmpty(request.BodyContent?.Name)) return ApiGatewayV2Result.BadRequest(new ErrorResponse("Name is required")); diff --git a/src/Envelopes/MinimalLambda.Envelopes.CloudWatchLogs/README.md b/src/Envelopes/MinimalLambda.Envelopes.CloudWatchLogs/README.md index ad7da84f..8f139f1b 100644 --- a/src/Envelopes/MinimalLambda.Envelopes.CloudWatchLogs/README.md +++ b/src/Envelopes/MinimalLambda.Envelopes.CloudWatchLogs/README.md @@ -39,7 +39,7 @@ var lambda = builder.Build(); // CloudWatchLogsEnvelope provides access to the CloudWatch Logs event with each log message // deserialized into type T lambda.MapHandler( - ([Event] CloudWatchLogsEnvelope logs, ILogger logger) => + ([FromEvent] CloudWatchLogsEnvelope logs, ILogger logger) => { foreach (var logEvent in logs.AwslogsContent!.LogEvents) { diff --git a/src/Envelopes/MinimalLambda.Envelopes.Kafka/README.md b/src/Envelopes/MinimalLambda.Envelopes.Kafka/README.md index b06bc82c..6479bdf1 100644 --- a/src/Envelopes/MinimalLambda.Envelopes.Kafka/README.md +++ b/src/Envelopes/MinimalLambda.Envelopes.Kafka/README.md @@ -31,7 +31,7 @@ var lambda = builder.Build(); // KafkaEnvelope provides access to the Kafka event and deserialized OrderEvent payloads lambda.MapHandler( - ([Event] KafkaEnvelope envelope, ILogger logger) => + ([FromEvent] KafkaEnvelope envelope, ILogger logger) => { foreach (var topic in envelope.Records) { diff --git a/src/Envelopes/MinimalLambda.Envelopes.Kinesis/README.md b/src/Envelopes/MinimalLambda.Envelopes.Kinesis/README.md index a308e241..67888405 100644 --- a/src/Envelopes/MinimalLambda.Envelopes.Kinesis/README.md +++ b/src/Envelopes/MinimalLambda.Envelopes.Kinesis/README.md @@ -30,7 +30,7 @@ var lambda = builder.Build(); // KinesisEnvelope provides access to the Kinesis event and deserialized StreamRecord payloads lambda.MapHandler( - ([Event] KinesisEnvelope envelope, ILogger logger) => + ([FromEvent] KinesisEnvelope envelope, ILogger logger) => { foreach (var record in envelope.Records) { diff --git a/src/Envelopes/MinimalLambda.Envelopes.KinesisFirehose/README.md b/src/Envelopes/MinimalLambda.Envelopes.KinesisFirehose/README.md index 6f855bc2..dac8e8be 100644 --- a/src/Envelopes/MinimalLambda.Envelopes.KinesisFirehose/README.md +++ b/src/Envelopes/MinimalLambda.Envelopes.KinesisFirehose/README.md @@ -38,7 +38,7 @@ var lambda = builder.Build(); // KinesisFirehoseEventEnvelope provides the Firehose event with deserialized records // KinesisFirehoseResponseEnvelope wraps the response and serializes the transformed data lambda.MapHandler( - ([Event] KinesisFirehoseEventEnvelope request, ILogger logger) => + ([FromEvent] KinesisFirehoseEventEnvelope request, ILogger logger) => { var response = new KinesisFirehoseResponseEnvelope { diff --git a/src/Envelopes/MinimalLambda.Envelopes.Sns/README.md b/src/Envelopes/MinimalLambda.Envelopes.Sns/README.md index 28cfb540..a63aaf28 100644 --- a/src/Envelopes/MinimalLambda.Envelopes.Sns/README.md +++ b/src/Envelopes/MinimalLambda.Envelopes.Sns/README.md @@ -30,7 +30,7 @@ var lambda = builder.Build(); // SnsEnvelope provides access to the SNS event and deserialized Message payloads lambda.MapHandler( - ([Event] SnsEnvelope envelope, ILogger logger) => + ([FromEvent] SnsEnvelope envelope, ILogger logger) => { foreach (var record in envelope.Records) { diff --git a/src/Envelopes/MinimalLambda.Envelopes.Sqs/README.md b/src/Envelopes/MinimalLambda.Envelopes.Sqs/README.md index 774535c0..7f3a881b 100644 --- a/src/Envelopes/MinimalLambda.Envelopes.Sqs/README.md +++ b/src/Envelopes/MinimalLambda.Envelopes.Sqs/README.md @@ -33,7 +33,7 @@ var lambda = builder.Build(); // SqsEnvelope provides access to the SQS event and deserialized Message payloads lambda.MapHandler( - ([Event] SqsEnvelope envelope, ILogger logger) => + ([FromEvent] SqsEnvelope envelope, ILogger logger) => { // In order to handle any errors or unprocessed messages, you must return a SQSBatchResponse var batchResponse = new SQSBatchResponse(); diff --git a/src/Envelopes/MinimalLambda.Envelopes/BaseHttpResultExtensions.cs b/src/Envelopes/MinimalLambda.Envelopes/BaseHttpResultExtensions.cs index 5c7cb09c..1a7307ff 100644 --- a/src/Envelopes/MinimalLambda.Envelopes/BaseHttpResultExtensions.cs +++ b/src/Envelopes/MinimalLambda.Envelopes/BaseHttpResultExtensions.cs @@ -3,21 +3,21 @@ namespace MinimalLambda.Envelopes; /// Provides factory extension methods for creating HTTP results. public static class BaseHttpResultExtensions { - extension(IHttpResult) - where THttpResult : IHttpResult + extension(IHttpResult) + where TResult : IHttpResult { /// Creates an HTTP result with the specified status code. /// The HTTP status code. /// An HTTP result with the status code. - public static THttpResult StatusCode(int statusCode) => - THttpResult.Create(statusCode, null, new Dictionary(), false); + public static TResult StatusCode(int statusCode) => + TResult.Create(statusCode, null, new Dictionary(), false); /// Creates a text/plain HTTP result. /// The HTTP status code. /// The plain text response body. /// An HTTP result with text/plain content type. - public static THttpResult Text(int statusCode, string body) => - THttpResult + public static TResult Text(int statusCode, string body) => + TResult .Create( statusCode, null, @@ -34,8 +34,8 @@ public static THttpResult Text(int statusCode, string body) => /// The HTTP status code. /// The content to serialize as JSON. /// An HTTP result with application/json content type. - public static THttpResult Json(int statusCode, T bodyContent) => - THttpResult.Create( + public static TResult Json(int statusCode, T bodyContent) => + TResult.Create( statusCode, bodyContent, new Dictionary @@ -46,13 +46,13 @@ public static THttpResult Json(int statusCode, T bodyContent) => ); } - extension(THttpResult result) - where THttpResult : IHttpResult + extension(TResult result) + where TResult : IHttpResult { /// Applies customizations to the result. /// An action to customize the result properties. /// The same instance for method chaining. - public THttpResult Customize(Action customizer) + public TResult Customize(Action customizer) { customizer(result); return result; diff --git a/src/Envelopes/MinimalLambda.Envelopes/HttpResultExtensions.cs b/src/Envelopes/MinimalLambda.Envelopes/HttpResultExtensions.cs index ad815d59..e4081aaa 100644 --- a/src/Envelopes/MinimalLambda.Envelopes/HttpResultExtensions.cs +++ b/src/Envelopes/MinimalLambda.Envelopes/HttpResultExtensions.cs @@ -5,8 +5,8 @@ namespace MinimalLambda.Envelopes; /// Provides convenience extension methods for common HTTP status codes. public static class HttpResultExtensions { - extension(IHttpResult) - where THttpResult : IHttpResult + extension(IHttpResult) + where TResult : IHttpResult { // ── 200 Ok ─────────────────────────────────────────────────────────────────────── @@ -14,175 +14,155 @@ public static class HttpResultExtensions /// The type of content to return. /// The response content to serialize. /// An HTTP 200 result with JSON content. - public static THttpResult Ok(T bodyContent) => - BaseHttpResultExtensions.Json(StatusCodes.Status200OK, bodyContent); + public static TResult Ok(T bodyContent) => + BaseHttpResultExtensions.Json(StatusCodes.Status200OK, bodyContent); /// Creates a 200 OK response. /// An HTTP 200 result. - public static THttpResult Ok() => - BaseHttpResultExtensions.StatusCode(StatusCodes.Status200OK); + public static TResult Ok() => + BaseHttpResultExtensions.StatusCode(StatusCodes.Status200OK); // ── 201 Created ────────────────────────────────────────────────────────────────── /// Creates a 201 Created response. /// An HTTP 201 result. - public static THttpResult Created() => - BaseHttpResultExtensions.StatusCode(StatusCodes.Status201Created); + public static TResult Created() => + BaseHttpResultExtensions.StatusCode(StatusCodes.Status201Created); /// Creates a 201 Created response with content. /// The type of content to return. /// The response content to serialize. /// An HTTP 201 result with JSON content. - public static THttpResult Created(T bodyContent) => - BaseHttpResultExtensions.Json( - StatusCodes.Status201Created, - bodyContent - ); + public static TResult Created(T bodyContent) => + BaseHttpResultExtensions.Json(StatusCodes.Status201Created, bodyContent); // ── 202 Accepted ───────────────────────────────────────────────────────────────── /// Creates a 202 Accepted response. /// An HTTP 202 result. - public static THttpResult Accepted() => - BaseHttpResultExtensions.StatusCode(StatusCodes.Status202Accepted); + public static TResult Accepted() => + BaseHttpResultExtensions.StatusCode(StatusCodes.Status202Accepted); /// Creates a 202 Accepted response with content. /// The type of content to return. /// The response content to serialize. /// An HTTP 202 result with JSON content. - public static THttpResult Accepted(T bodyContent) => - BaseHttpResultExtensions.Json( - StatusCodes.Status202Accepted, - bodyContent - ); + public static TResult Accepted(T bodyContent) => + BaseHttpResultExtensions.Json(StatusCodes.Status202Accepted, bodyContent); // ── 204 No Content ─────────────────────────────────────────────────────────────── /// Creates a 204 No Content response. /// An HTTP 204 result. - public static THttpResult NoContent() => - BaseHttpResultExtensions.StatusCode(StatusCodes.Status204NoContent); + public static TResult NoContent() => + BaseHttpResultExtensions.StatusCode(StatusCodes.Status204NoContent); // ── 301 Moved Permanently ──────────────────────────────────────────────────────── /// Creates a 301 Moved Permanently response. /// An HTTP 301 result. - public static THttpResult MovedPermanently() => - BaseHttpResultExtensions.StatusCode(StatusCodes.Status301MovedPermanently); + public static TResult MovedPermanently() => + BaseHttpResultExtensions.StatusCode(StatusCodes.Status301MovedPermanently); /// Creates a 301 Moved Permanently response with a location. /// The URI of the redirect target. /// An HTTP 301 result with Location header. - public static THttpResult MovedPermanently(string location) => + public static TResult MovedPermanently(string location) => BaseHttpResultExtensions - .StatusCode(StatusCodes.Status301MovedPermanently) + .StatusCode(StatusCodes.Status301MovedPermanently) .Customize(result => result.Headers["Location"] = location); // ── 302 Found ──────────────────────────────────────────────────────────────────── /// Creates a 302 Found response. /// An HTTP 302 result. - public static THttpResult Found() => - BaseHttpResultExtensions.StatusCode(StatusCodes.Status302Found); + public static TResult Found() => + BaseHttpResultExtensions.StatusCode(StatusCodes.Status302Found); /// Creates a 302 Found response with a location. /// The URI of the redirect target. /// An HTTP 302 result with Location header. - public static THttpResult Found(string location) => + public static TResult Found(string location) => BaseHttpResultExtensions - .StatusCode(StatusCodes.Status302Found) + .StatusCode(StatusCodes.Status302Found) .Customize(result => result.Headers["Location"] = location); // ── 400 Bad Request ────────────────────────────────────────────────────────────── /// Creates a 400 Bad Request response. /// An HTTP 400 result. - public static THttpResult BadRequest() => - BaseHttpResultExtensions.StatusCode(StatusCodes.Status400BadRequest); + public static TResult BadRequest() => + BaseHttpResultExtensions.StatusCode(StatusCodes.Status400BadRequest); /// Creates a 400 Bad Request response with content. /// The type of content to return. /// The response content to serialize. /// An HTTP 400 result with JSON content. - public static THttpResult BadRequest(T bodyContent) => - BaseHttpResultExtensions.Json( - StatusCodes.Status400BadRequest, - bodyContent - ); + public static TResult BadRequest(T bodyContent) => + BaseHttpResultExtensions.Json(StatusCodes.Status400BadRequest, bodyContent); // ── 401 Unauthorized ───────────────────────────────────────────────────────────── /// Creates a 401 Unauthorized response. /// An HTTP 401 result. - public static THttpResult Unauthorized() => - BaseHttpResultExtensions.StatusCode(StatusCodes.Status401Unauthorized); + public static TResult Unauthorized() => + BaseHttpResultExtensions.StatusCode(StatusCodes.Status401Unauthorized); // ── 403 Forbidden ──────────────────────────────────────────────────────────────── /// Creates a 403 Forbidden response. /// An HTTP 403 result. - public static THttpResult Forbidden() => - BaseHttpResultExtensions.StatusCode(StatusCodes.Status403Forbidden); + public static TResult Forbidden() => + BaseHttpResultExtensions.StatusCode(StatusCodes.Status403Forbidden); /// Creates a 403 Forbidden response with content. /// The type of content to return. /// The response content to serialize. /// An HTTP 403 result with JSON content. - public static THttpResult Forbidden(T bodyContent) => - BaseHttpResultExtensions.Json( - StatusCodes.Status403Forbidden, - bodyContent - ); + public static TResult Forbidden(T bodyContent) => + BaseHttpResultExtensions.Json(StatusCodes.Status403Forbidden, bodyContent); // ── 404 Not Found ──────────────────────────────────────────────────────────────── /// Creates a 404 Not Found response. /// An HTTP 404 result. - public static THttpResult NotFound() => - BaseHttpResultExtensions.StatusCode(StatusCodes.Status404NotFound); + public static TResult NotFound() => + BaseHttpResultExtensions.StatusCode(StatusCodes.Status404NotFound); /// Creates a 404 Not Found response with content. /// The type of content to return. /// The response content to serialize. /// An HTTP 404 result with JSON content. - public static THttpResult NotFound(T bodyContent) => - BaseHttpResultExtensions.Json( - StatusCodes.Status404NotFound, - bodyContent - ); + public static TResult NotFound(T bodyContent) => + BaseHttpResultExtensions.Json(StatusCodes.Status404NotFound, bodyContent); // ── 409 Conflict ───────────────────────────────────────────────────────────────── /// Creates a 409 Conflict response. /// An HTTP 409 result. - public static THttpResult Conflict() => - BaseHttpResultExtensions.StatusCode(StatusCodes.Status409Conflict); + public static TResult Conflict() => + BaseHttpResultExtensions.StatusCode(StatusCodes.Status409Conflict); /// Creates a 409 Conflict response with content. /// The type of content to return. /// The response content to serialize. /// An HTTP 409 result with JSON content. - public static THttpResult Conflict(T bodyContent) => - BaseHttpResultExtensions.Json( - StatusCodes.Status409Conflict, - bodyContent - ); + public static TResult Conflict(T bodyContent) => + BaseHttpResultExtensions.Json(StatusCodes.Status409Conflict, bodyContent); // ── 422 Unprocessable Entity ───────────────────────────────────────────────────── /// Creates a 422 Unprocessable Entity response. /// An HTTP 422 result. - public static THttpResult UnprocessableEntity() => - BaseHttpResultExtensions.StatusCode( - StatusCodes.Status422UnprocessableEntity - ); + public static TResult UnprocessableEntity() => + BaseHttpResultExtensions.StatusCode(StatusCodes.Status422UnprocessableEntity); /// Creates a 422 Unprocessable Entity response with content. /// The type of content to return. /// The response content to serialize. /// An HTTP 422 result with JSON content. - public static THttpResult UnprocessableEntity(T bodyContent) => - BaseHttpResultExtensions.Json( + public static TResult UnprocessableEntity(T bodyContent) => + BaseHttpResultExtensions.Json( StatusCodes.Status422UnprocessableEntity, bodyContent ); @@ -191,17 +171,15 @@ public static THttpResult UnprocessableEntity(T bodyContent) => /// Creates a 500 Internal Server Error response. /// An HTTP 500 result. - public static THttpResult InternalServerError() => - BaseHttpResultExtensions.StatusCode( - StatusCodes.Status500InternalServerError - ); + public static TResult InternalServerError() => + BaseHttpResultExtensions.StatusCode(StatusCodes.Status500InternalServerError); /// Creates a 500 Internal Server Error response with content. /// The type of content to return. /// The response content to serialize. /// An HTTP 500 result with JSON content. - public static THttpResult InternalServerError(T bodyContent) => - BaseHttpResultExtensions.Json( + public static TResult InternalServerError(T bodyContent) => + BaseHttpResultExtensions.Json( StatusCodes.Status500InternalServerError, bodyContent ); diff --git a/src/MinimalLambda.OpenTelemetry/README.md b/src/MinimalLambda.OpenTelemetry/README.md index 68aa3be4..28fd759b 100644 --- a/src/MinimalLambda.OpenTelemetry/README.md +++ b/src/MinimalLambda.OpenTelemetry/README.md @@ -98,7 +98,7 @@ var lambda = builder.Build(); // Enable automatic tracing for Lambda invocations lambda.UseOpenTelemetryTracing(); -lambda.MapHandler(([Event] string input) => $"Hello {input}!"); +lambda.MapHandler(([FromEvent] string input) => $"Hello {input}!"); // Flush traces on Lambda shutdown lambda.OnShutdownFlushTracer(); @@ -179,7 +179,7 @@ builder.Services.AddSingleton(); var lambda = builder.Build(); // In your handler: -lambda.MapHandler(([Event] Request request, Instrumentation instrumentation) => +lambda.MapHandler(([FromEvent] Request request, Instrumentation instrumentation) => { using var activity = instrumentation.ActivitySource.StartActivity("ProcessRequest"); activity?.SetAttribute("request.name", request.Name); diff --git a/src/MinimalLambda.SourceGenerators/Diagnostics/DiagnosticGenerator.cs b/src/MinimalLambda.SourceGenerators/Diagnostics/DiagnosticGenerator.cs index 703aef3a..e6d95c28 100644 --- a/src/MinimalLambda.SourceGenerators/Diagnostics/DiagnosticGenerator.cs +++ b/src/MinimalLambda.SourceGenerators/Diagnostics/DiagnosticGenerator.cs @@ -16,7 +16,7 @@ internal static List GenerateDiagnostics(CompilationInfo compilation // Validate parameters foreach (var invocationInfo in delegateInfos) - // check for multiple parameters that use the `[Event]` attribute + // check for multiple parameters that use the `[FromEvent]` attribute if ( invocationInfo.DelegateInfo.Parameters.Count(p => p.Source == ParameterSource.Event) > 1 @@ -28,7 +28,7 @@ internal static List GenerateDiagnostics(CompilationInfo compilation Diagnostic.Create( Diagnostics.MultipleParametersUseAttribute, p.LocationInfo?.ToLocation(), - AttributeConstants.EventAttribute + AttributeConstants.FromEventAttribute ) ) ); diff --git a/src/MinimalLambda.SourceGenerators/GeneratorConstants.cs b/src/MinimalLambda.SourceGenerators/GeneratorConstants.cs index 7c64ce10..0ab2717f 100644 --- a/src/MinimalLambda.SourceGenerators/GeneratorConstants.cs +++ b/src/MinimalLambda.SourceGenerators/GeneratorConstants.cs @@ -31,6 +31,8 @@ internal static class AttributeConstants { internal const string EventAttribute = "MinimalLambda.Builder.EventAttribute"; + internal const string FromEventAttribute = "MinimalLambda.Builder.FromEventAttribute"; + internal const string FromKeyedService = "Microsoft.Extensions.DependencyInjection.FromKeyedServicesAttribute"; } diff --git a/src/MinimalLambda.SourceGenerators/Models/ParameterInfo.cs b/src/MinimalLambda.SourceGenerators/Models/ParameterInfo.cs index c2f82cb9..50ad63e1 100644 --- a/src/MinimalLambda.SourceGenerators/Models/ParameterInfo.cs +++ b/src/MinimalLambda.SourceGenerators/Models/ParameterInfo.cs @@ -57,6 +57,7 @@ private static ( switch (attribute.AttributeClass?.ToString()) { case AttributeConstants.EventAttribute: + case AttributeConstants.FromEventAttribute: return (ParameterSource.Event, null); case AttributeConstants.FromKeyedService: diff --git a/src/MinimalLambda.Testing/LambdaApplicationFactoryContentRootAttribute.cs b/src/MinimalLambda.Testing/LambdaApplicationFactoryContentRootAttribute.cs index 9cf33ae1..f3d11fea 100644 --- a/src/MinimalLambda.Testing/LambdaApplicationFactoryContentRootAttribute.cs +++ b/src/MinimalLambda.Testing/LambdaApplicationFactoryContentRootAttribute.cs @@ -12,8 +12,8 @@ namespace MinimalLambda.Testing; /// -/// Metadata that uses to find out the -/// content root for the web application represented by TEntryPoint. +/// Metadata that uses to find out the content +/// root for the web application represented by TEntryPoint. /// will iterate over all the instances of /// , filter the instances whose /// is equal to TEntryPoint , order them diff --git a/src/MinimalLambda/Builder/EventAttribute.cs b/src/MinimalLambda/Builder/EventAttribute.cs index 842681d3..82e69df5 100644 --- a/src/MinimalLambda/Builder/EventAttribute.cs +++ b/src/MinimalLambda/Builder/EventAttribute.cs @@ -21,12 +21,11 @@ namespace MinimalLambda.Builder; /// /// /// -/// public async Task HandleEvent([Event] MyEventType myEvent, ILogger logger, CancellationToken ct) -/// { -/// logger.LogInformation("Received event: {EventId}", myEvent.Id); -/// await ProcessEventAsync(@event, ct); -/// } +/// lambda.MapHandler(([Event] MyEvent myEvent) => $"Hello, {myEvent.Name}!"); /// /// +[Obsolete( + "This Attribute is obsolete because it does not follow .NET naming conventions and can cuse naming conflicts with System.Diagnostics.Tracing.EventAttribute. Use FromEventAttribute instead." +)] [AttributeUsage(AttributeTargets.Parameter)] public sealed class EventAttribute : Attribute; diff --git a/src/MinimalLambda/Builder/FromEventAttribute.cs b/src/MinimalLambda/Builder/FromEventAttribute.cs new file mode 100644 index 00000000..a21fe82b --- /dev/null +++ b/src/MinimalLambda/Builder/FromEventAttribute.cs @@ -0,0 +1,28 @@ +namespace MinimalLambda.Builder; + +/// Marks a parameter to receive the deserialized Lambda event object. +/// +/// +/// The is used with the source generator to indicate that +/// a handler method parameter should be injected with the deserialized event from the current +/// Lambda invocation. This attribute is applied to the event parameter in handler methods that +/// are registered using , +/// , or related extension methods. +/// +/// +/// This attribute is only valid on method parameters and is processed at compile-time by the +/// source generator to generate the necessary wiring code. +/// +/// +/// Important: Only one parameter per handler method can be decorated with this +/// attribute. Applying to multiple parameters in the same +/// handler will result in a compile-time error from the source generator. +/// +/// +/// +/// +/// lambda.MapHandler(([FromEvent] MyEvent myEvent) => $"Hello, {myEvent.Name}!"); +/// +/// +[AttributeUsage(AttributeTargets.Parameter)] +public sealed class FromEventAttribute : Attribute; diff --git a/src/MinimalLambda/README.md b/src/MinimalLambda/README.md index 0e2d0318..8b816d35 100644 --- a/src/MinimalLambda/README.md +++ b/src/MinimalLambda/README.md @@ -13,7 +13,7 @@ var builder = LambdaApplication.CreateBuilder(); builder.Services.AddScoped(); var lambda = builder.Build(); -lambda.MapHandler(([Event] string input, IMyService service) => +lambda.MapHandler(([FromEvent] string input, IMyService service) => service.Process(input)); await lambda.RunAsync(); @@ -57,17 +57,17 @@ using Microsoft.Extensions.Hosting; var builder = LambdaApplication.CreateBuilder(); var lambda = builder.Build(); -// The [Event] attribute marks the parameter that receives the deserialized Lambda event -lambda.MapHandler(([Event] string input) => $"Hello {input}!"); +// The [FromEvent] attribute marks the parameter that receives the deserialized Lambda event +lambda.MapHandler(([FromEvent] string input) => $"Hello {input}!"); await lambda.RunAsync(); ``` -The `[Event]` attribute tells the framework which parameter receives the deserialized event. You can +The `[FromEvent]` attribute tells the framework which parameter receives the deserialized event. You can also inject dependencies: ```csharp -lambda.MapHandler(([Event] Order order, IOrderService service) => +lambda.MapHandler(([FromEvent] Order order, IOrderService service) => service.Process(order) ); ``` @@ -131,14 +131,14 @@ lambda.OnShutdown(ITelemetryService telemetryService => Register your Lambda handler with the builder. The framework uses source generation to analyze your handler signature: -- The `[Event]` attribute marks the input parameter type +- The `[FromEvent]` attribute marks the input parameter type - The return type determines the response type - Source generation handles serialization/deserialization automatically Handlers can inject dependencies alongside the event: ```csharp -lambda.MapHandler(([Event] Order order, IOrderService service) => +lambda.MapHandler(([FromEvent] Order order, IOrderService service) => service.Process(order) // Return type automatically serialized to JSON ); ``` diff --git a/tests/MinimalLambda.SourceGenerators.UnitTests/DiagnosticTests.cs b/tests/MinimalLambda.SourceGenerators.UnitTests/DiagnosticTests.cs index 363d35f6..a36c90b3 100644 --- a/tests/MinimalLambda.SourceGenerators.UnitTests/DiagnosticTests.cs +++ b/tests/MinimalLambda.SourceGenerators.UnitTests/DiagnosticTests.cs @@ -66,7 +66,7 @@ public void Test_MultipleParametersWithRequestAttribute() var lambda = builder.Build(); - lambda.MapHandler(([Event] string input1, [Event] string input2) => "hello world"); + lambda.MapHandler(([FromEvent] string input1, [FromEvent] string input2) => "hello world"); await lambda.RunAsync(); """ diff --git a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/BlockLambdaVerifyTests.Test_BlockLambda_AllInputSources#LambdaHandler.g.verified.cs b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/BlockLambdaVerifyTests.Test_BlockLambda_AllInputSources#LambdaHandler.g.verified.cs index d98e066e..8216dce2 100644 --- a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/BlockLambdaVerifyTests.Test_BlockLambda_AllInputSources#LambdaHandler.g.verified.cs +++ b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/BlockLambdaVerifyTests.Test_BlockLambda_AllInputSources#LambdaHandler.g.verified.cs @@ -43,7 +43,7 @@ file static class GeneratedLambdaInvocationBuilderExtensions private const string ResponseFeatureProviderKey = "__ResponseFeatureProvider"; // Location: InputFile.cs(14,8) - [InterceptsLocation(1, "VP2f+uiZdS+PotWEzQbiljsBAABJbnB1dEZpbGUuY3M=")] + [InterceptsLocation(1, "Tx1x72WT0aa+xpOr41o/dzsBAABJbnB1dEZpbGUuY3M=")] internal static ILambdaInvocationBuilder MapHandlerInterceptor0( this ILambdaInvocationBuilder application, Delegate handler diff --git a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/BlockLambdaVerifyTests.Test_BlockLambda_NoReturn_TypeCast#LambdaHandler.g.verified.cs b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/BlockLambdaVerifyTests.Test_BlockLambda_NoReturn_TypeCast#LambdaHandler.g.verified.cs index 0e2b0530..d675980b 100644 --- a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/BlockLambdaVerifyTests.Test_BlockLambda_NoReturn_TypeCast#LambdaHandler.g.verified.cs +++ b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/BlockLambdaVerifyTests.Test_BlockLambda_NoReturn_TypeCast#LambdaHandler.g.verified.cs @@ -43,7 +43,7 @@ file static class GeneratedLambdaInvocationBuilderExtensions private const string ResponseFeatureProviderKey = "__ResponseFeatureProvider"; // Location: InputFile.cs(10,8) - [InterceptsLocation(1, "ng4qOHWnkJh4C4VlurOGMtoAAABJbnB1dEZpbGUuY3M=")] + [InterceptsLocation(1, "x0XA1nde6vAUjFMeY2ZDTdoAAABJbnB1dEZpbGUuY3M=")] internal static ILambdaInvocationBuilder MapHandlerInterceptor0( this ILambdaInvocationBuilder application, Delegate handler diff --git a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/BlockLambdaVerifyTests.Test_BlockLambda_ReturnExplicitType#LambdaHandler.g.verified.cs b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/BlockLambdaVerifyTests.Test_BlockLambda_ReturnExplicitType#LambdaHandler.g.verified.cs index ad101d36..341b6b4b 100644 --- a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/BlockLambdaVerifyTests.Test_BlockLambda_ReturnExplicitType#LambdaHandler.g.verified.cs +++ b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/BlockLambdaVerifyTests.Test_BlockLambda_ReturnExplicitType#LambdaHandler.g.verified.cs @@ -43,7 +43,7 @@ file static class GeneratedLambdaInvocationBuilderExtensions private const string ResponseFeatureProviderKey = "__ResponseFeatureProvider"; // Location: InputFile.cs(9,8) - [InterceptsLocation(1, "w4moLaByZsxXLuN4WecQp8wAAABJbnB1dEZpbGUuY3M=")] + [InterceptsLocation(1, "nm5FtUI+NJquLXB1CZ0sIswAAABJbnB1dEZpbGUuY3M=")] internal static ILambdaInvocationBuilder MapHandlerInterceptor0( this ILambdaInvocationBuilder application, Delegate handler diff --git a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/BlockLambdaVerifyTests.Test_BlockLambda_ReturnImplicitNullable#LambdaHandler.g.verified.cs b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/BlockLambdaVerifyTests.Test_BlockLambda_ReturnImplicitNullable#LambdaHandler.g.verified.cs index 8a4d7091..6e4fdd97 100644 --- a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/BlockLambdaVerifyTests.Test_BlockLambda_ReturnImplicitNullable#LambdaHandler.g.verified.cs +++ b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/BlockLambdaVerifyTests.Test_BlockLambda_ReturnImplicitNullable#LambdaHandler.g.verified.cs @@ -43,7 +43,7 @@ file static class GeneratedLambdaInvocationBuilderExtensions private const string ResponseFeatureProviderKey = "__ResponseFeatureProvider"; // Location: InputFile.cs(8,8) - [InterceptsLocation(1, "DqY8rinA+uHB6sl663XA8a4AAABJbnB1dEZpbGUuY3M=")] + [InterceptsLocation(1, "utXmh7WLuYyG7VwRDFaLbq4AAABJbnB1dEZpbGUuY3M=")] internal static ILambdaInvocationBuilder MapHandlerInterceptor0( this ILambdaInvocationBuilder application, Delegate handler diff --git a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/BlockLambdaVerifyTests.Test_BlockLambda_ReturnString#LambdaHandler.g.verified.cs b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/BlockLambdaVerifyTests.Test_BlockLambda_ReturnString#LambdaHandler.g.verified.cs index cef6f817..e85d05a1 100644 --- a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/BlockLambdaVerifyTests.Test_BlockLambda_ReturnString#LambdaHandler.g.verified.cs +++ b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/BlockLambdaVerifyTests.Test_BlockLambda_ReturnString#LambdaHandler.g.verified.cs @@ -43,7 +43,7 @@ file static class GeneratedLambdaInvocationBuilderExtensions private const string ResponseFeatureProviderKey = "__ResponseFeatureProvider"; // Location: InputFile.cs(8,8) - [InterceptsLocation(1, "4KtVaSPugK/Yn6yEqkiSkq4AAABJbnB1dEZpbGUuY3M=")] + [InterceptsLocation(1, "YyltEHxaNav+M48OGFvSga4AAABJbnB1dEZpbGUuY3M=")] internal static ILambdaInvocationBuilder MapHandlerInterceptor0( this ILambdaInvocationBuilder application, Delegate handler diff --git a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_ComplexInput_ComplexOutput#LambdaHandler.g.verified.cs b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_ComplexInput_ComplexOutput#LambdaHandler.g.verified.cs index 9426fe5a..375863a3 100644 --- a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_ComplexInput_ComplexOutput#LambdaHandler.g.verified.cs +++ b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_ComplexInput_ComplexOutput#LambdaHandler.g.verified.cs @@ -43,7 +43,7 @@ file static class GeneratedLambdaInvocationBuilderExtensions private const string ResponseFeatureProviderKey = "__ResponseFeatureProvider"; // Location: InputFile.cs(10,8) - [InterceptsLocation(1, "ixKezoN6SQ9ZJuIWXUEMnOYAAABJbnB1dEZpbGUuY3M=")] + [InterceptsLocation(1, "k8jU1POB8TXl/XtywGzhweYAAABJbnB1dEZpbGUuY3M=")] internal static ILambdaInvocationBuilder MapHandlerInterceptor0( this ILambdaInvocationBuilder application, Delegate handler diff --git a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_InputDi_Async#LambdaHandler.g.verified.cs b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_InputDi_Async#LambdaHandler.g.verified.cs index 6aa3fc24..c9a53e08 100644 --- a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_InputDi_Async#LambdaHandler.g.verified.cs +++ b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_InputDi_Async#LambdaHandler.g.verified.cs @@ -43,7 +43,7 @@ file static class GeneratedLambdaInvocationBuilderExtensions private const string ResponseFeatureProviderKey = "__ResponseFeatureProvider"; // Location: InputFile.cs(9,8) - [InterceptsLocation(1, "MM4MsQPkcbIYHWAtaye0xa8AAABJbnB1dEZpbGUuY3M=")] + [InterceptsLocation(1, "RYU1ACjUCJAF6VKP6xz4f68AAABJbnB1dEZpbGUuY3M=")] internal static ILambdaInvocationBuilder MapHandlerInterceptor0( this ILambdaInvocationBuilder application, Delegate handler diff --git a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_InputDi_AsyncAndAwait#LambdaHandler.g.verified.cs b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_InputDi_AsyncAndAwait#LambdaHandler.g.verified.cs index f9105d82..67fc5e20 100644 --- a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_InputDi_AsyncAndAwait#LambdaHandler.g.verified.cs +++ b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_InputDi_AsyncAndAwait#LambdaHandler.g.verified.cs @@ -43,7 +43,7 @@ file static class GeneratedLambdaInvocationBuilderExtensions private const string ResponseFeatureProviderKey = "__ResponseFeatureProvider"; // Location: InputFile.cs(10,8) - [InterceptsLocation(1, "gPwlNZ7yUMUE03RWPlHggc0AAABJbnB1dEZpbGUuY3M=")] + [InterceptsLocation(1, "YAxktVM2tLACcLf16mEVcc0AAABJbnB1dEZpbGUuY3M=")] internal static ILambdaInvocationBuilder MapHandlerInterceptor0( this ILambdaInvocationBuilder application, Delegate handler diff --git a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_InputDi_AsyncAndAwait_EventAndResponseDifferentNamespace#LambdaHandler.g.verified.cs b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_InputDi_AsyncAndAwait_EventAndResponseDifferentNamespace#LambdaHandler.g.verified.cs index fbb57fd5..31044848 100644 --- a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_InputDi_AsyncAndAwait_EventAndResponseDifferentNamespace#LambdaHandler.g.verified.cs +++ b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_InputDi_AsyncAndAwait_EventAndResponseDifferentNamespace#LambdaHandler.g.verified.cs @@ -43,7 +43,7 @@ file static class GeneratedLambdaInvocationBuilderExtensions private const string ResponseFeatureProviderKey = "__ResponseFeatureProvider"; // Location: InputFile.cs(11,8) - [InterceptsLocation(1, "8WhODzG6WGWPy7Q+FAmYNuAAAABJbnB1dEZpbGUuY3M=")] + [InterceptsLocation(1, "g8LHgWNG7I4SppTaP2NXcuAAAABJbnB1dEZpbGUuY3M=")] internal static ILambdaInvocationBuilder MapHandlerInterceptor0( this ILambdaInvocationBuilder application, Delegate handler diff --git a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_InputStream#LambdaHandler.g.verified.cs b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_InputStream#LambdaHandler.g.verified.cs index 6cc7aecb..4a559981 100644 --- a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_InputStream#LambdaHandler.g.verified.cs +++ b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_InputStream#LambdaHandler.g.verified.cs @@ -43,7 +43,7 @@ file static class GeneratedLambdaInvocationBuilderExtensions private const string ResponseFeatureProviderKey = "__ResponseFeatureProvider"; // Location: InputFile.cs(10,8) - [InterceptsLocation(1, "kMEdRureGinS9vjuOg9cX8AAAABJbnB1dEZpbGUuY3M=")] + [InterceptsLocation(1, "j1cZzS1JRw4YpXVdsmK4icAAAABJbnB1dEZpbGUuY3M=")] internal static ILambdaInvocationBuilder MapHandlerInterceptor0( this ILambdaInvocationBuilder application, Delegate handler diff --git a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_NullableInput_ReturnExplicitNullable#LambdaHandler.g.verified.cs b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_NullableInput_ReturnExplicitNullable#LambdaHandler.g.verified.cs index b6338c5d..41ec5ba6 100644 --- a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_NullableInput_ReturnExplicitNullable#LambdaHandler.g.verified.cs +++ b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_NullableInput_ReturnExplicitNullable#LambdaHandler.g.verified.cs @@ -43,7 +43,7 @@ file static class GeneratedLambdaInvocationBuilderExtensions private const string ResponseFeatureProviderKey = "__ResponseFeatureProvider"; // Location: InputFile.cs(8,8) - [InterceptsLocation(1, "EDNz6e5tefnWkx5Bq6QB3K4AAABJbnB1dEZpbGUuY3M=")] + [InterceptsLocation(1, "GzrEvlSIcRHrVreaVlX6r64AAABJbnB1dEZpbGUuY3M=")] internal static ILambdaInvocationBuilder MapHandlerInterceptor0( this ILambdaInvocationBuilder application, Delegate handler diff --git a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_NullableInput_ReturnImplicitNullable#LambdaHandler.g.verified.cs b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_NullableInput_ReturnImplicitNullable#LambdaHandler.g.verified.cs index 7f5a552e..df57ea28 100644 --- a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_NullableInput_ReturnImplicitNullable#LambdaHandler.g.verified.cs +++ b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_NullableInput_ReturnImplicitNullable#LambdaHandler.g.verified.cs @@ -43,7 +43,7 @@ file static class GeneratedLambdaInvocationBuilderExtensions private const string ResponseFeatureProviderKey = "__ResponseFeatureProvider"; // Location: InputFile.cs(8,8) - [InterceptsLocation(1, "hQau9yVjg5Tk/d7+kjXPVa4AAABJbnB1dEZpbGUuY3M=")] + [InterceptsLocation(1, "FyRpi+O01Le5sodA43elIa4AAABJbnB1dEZpbGUuY3M=")] internal static ILambdaInvocationBuilder MapHandlerInterceptor0( this ILambdaInvocationBuilder application, Delegate handler diff --git a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_ReturnExplicitType#LambdaHandler.g.verified.cs b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_ReturnExplicitType#LambdaHandler.g.verified.cs index 9086c67c..dd0d0ee4 100644 --- a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_ReturnExplicitType#LambdaHandler.g.verified.cs +++ b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/ExpressionLambdaVerifyTests.Test_ExpressionLambda_ReturnExplicitType#LambdaHandler.g.verified.cs @@ -43,7 +43,7 @@ file static class GeneratedLambdaInvocationBuilderExtensions private const string ResponseFeatureProviderKey = "__ResponseFeatureProvider"; // Location: InputFile.cs(9,8) - [InterceptsLocation(1, "bLWvoKINhFpNDAVeDD/J9swAAABJbnB1dEZpbGUuY3M=")] + [InterceptsLocation(1, "Omlg4OEyk26g8wXWjLDFPcwAAABJbnB1dEZpbGUuY3M=")] internal static ILambdaInvocationBuilder MapHandlerInterceptor0( this ILambdaInvocationBuilder application, Delegate handler diff --git a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/MethodHandlerVerifyTests.Test_MethodHandler_BlockBody_InputDiKeyedServices#LambdaHandler.g.verified.cs b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/MethodHandlerVerifyTests.Test_MethodHandler_BlockBody_InputDiKeyedServices#LambdaHandler.g.verified.cs index 1eecad0b..6fd88e89 100644 --- a/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/MethodHandlerVerifyTests.Test_MethodHandler_BlockBody_InputDiKeyedServices#LambdaHandler.g.verified.cs +++ b/tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/MethodHandlerVerifyTests.Test_MethodHandler_BlockBody_InputDiKeyedServices#LambdaHandler.g.verified.cs @@ -43,7 +43,7 @@ file static class GeneratedLambdaInvocationBuilderExtensions private const string ResponseFeatureProviderKey = "__ResponseFeatureProvider"; // Location: InputFile.cs(11,8) - [InterceptsLocation(1, "b0D41RfIehIYSzpiKIsdyfkAAABJbnB1dEZpbGUuY3M=")] + [InterceptsLocation(1, "WvA1V6ThyZ94LdZnpGUzR/kAAABJbnB1dEZpbGUuY3M=")] internal static ILambdaInvocationBuilder MapHandlerInterceptor0( this ILambdaInvocationBuilder application, Delegate handler diff --git a/tests/MinimalLambda.SourceGenerators.UnitTests/VerifyTests/BlockLambdaVerifyTests.cs b/tests/MinimalLambda.SourceGenerators.UnitTests/VerifyTests/BlockLambdaVerifyTests.cs index 910dd3a2..494801e3 100644 --- a/tests/MinimalLambda.SourceGenerators.UnitTests/VerifyTests/BlockLambdaVerifyTests.cs +++ b/tests/MinimalLambda.SourceGenerators.UnitTests/VerifyTests/BlockLambdaVerifyTests.cs @@ -15,7 +15,7 @@ await GeneratorTestHelpers.Verify( var lambda = builder.Build(); lambda.MapHandler( - IService ([Event] string input, IService service) => + IService ([FromEvent] string input, IService service) => { if (input == "other") { @@ -57,7 +57,7 @@ await GeneratorTestHelpers.Verify( var lambda = builder.Build(); lambda.MapHandler( - ([Event] string input) => + ([FromEvent] string input) => { return input; } @@ -216,7 +216,7 @@ await GeneratorTestHelpers.Verify( lambda.MapHandler( (Action)( - ([Event] string input, IService service) => + ([FromEvent] string input, IService service) => { Console.WriteLine("hello world"); } @@ -244,7 +244,7 @@ await GeneratorTestHelpers.Verify( var lambda = builder.Build(); lambda.MapHandler( - ([Event] string input, IService service) => + ([FromEvent] string input, IService service) => { return service.GetMessage(); } @@ -297,7 +297,7 @@ await GeneratorTestHelpers.Verify( lambda.MapHandler( ( - [Event] string request, + [FromEvent] string request, ILambdaContext context, CancellationToken cancellationToken, [FromKeyedServices("key0")] IService service0, diff --git a/tests/MinimalLambda.SourceGenerators.UnitTests/VerifyTests/ExpressionLambdaVerifyTests.cs b/tests/MinimalLambda.SourceGenerators.UnitTests/VerifyTests/ExpressionLambdaVerifyTests.cs index 648a77dd..9206fe1e 100644 --- a/tests/MinimalLambda.SourceGenerators.UnitTests/VerifyTests/ExpressionLambdaVerifyTests.cs +++ b/tests/MinimalLambda.SourceGenerators.UnitTests/VerifyTests/ExpressionLambdaVerifyTests.cs @@ -129,7 +129,7 @@ await GeneratorTestHelpers.Verify( var lambda = builder.Build(); lambda.MapHandler( - async ([Event] string input, IService service) => service.GetMessage().ToUpper() + async ([FromEvent] string input, IService service) => service.GetMessage().ToUpper() ); await lambda.RunAsync(); @@ -155,7 +155,7 @@ await GeneratorTestHelpers.Verify( var lambda = builder.Build(); lambda.MapHandler( - async ([Event] string input, IService service) => (await service.GetMessage()).ToUpper() + async ([FromEvent] string input, IService service) => (await service.GetMessage()).ToUpper() ); await lambda.RunAsync(); @@ -182,7 +182,7 @@ await GeneratorTestHelpers.Verify( var lambda = builder.Build(); lambda.MapHandler( - async ([Event] Event input, IService service) => + async ([FromEvent] Event input, IService service) => new Response((await service.GetMessage()).ToUpper()) ); @@ -215,7 +215,7 @@ await GeneratorTestHelpers.Verify( var lambda = builder.Build(); lambda.MapHandler( - IService ([Event] string input) => input == "other" ? new Service() : new OtherService() + IService ([FromEvent] string input) => input == "other" ? new Service() : new OtherService() ); await lambda.RunAsync(); @@ -249,7 +249,7 @@ await GeneratorTestHelpers.Verify( var builder = LambdaApplication.CreateBuilder(); var lambda = builder.Build(); - lambda.MapHandler(([Event] string? input, IService service) => service.GetMessage()); + lambda.MapHandler(([FromEvent] string? input, IService service) => service.GetMessage()); await lambda.RunAsync(); @@ -271,7 +271,7 @@ await GeneratorTestHelpers.Verify( var builder = LambdaApplication.CreateBuilder(); var lambda = builder.Build(); - lambda.MapHandler(string? ([Event] int? input, IService service) => service.GetMessage()); + lambda.MapHandler(string? ([FromEvent] int? input, IService service) => service.GetMessage()); await lambda.RunAsync(); @@ -298,7 +298,7 @@ await GeneratorTestHelpers.Verify( var lambda = builder.Build(); lambda.MapHandler( - async ([Event] CustomRequest request, IService service, ILambdaContext context) => + async ([FromEvent] CustomRequest request, IService service, ILambdaContext context) => new CustomResponse { Result = await service.GetMessage(), Success = true } ); @@ -431,7 +431,7 @@ await GeneratorTestHelpers.Verify( var lambda = builder.Build(); - lambda.MapHandler(([Event] Stream input) => { }); + lambda.MapHandler(([FromEvent] Stream input) => { }); await lambda.RunAsync(); """ diff --git a/tests/MinimalLambda.SourceGenerators.UnitTests/VerifyTests/StaticMethodVerifyTests.cs b/tests/MinimalLambda.SourceGenerators.UnitTests/VerifyTests/StaticMethodVerifyTests.cs index a47c5b83..8935a25a 100644 --- a/tests/MinimalLambda.SourceGenerators.UnitTests/VerifyTests/StaticMethodVerifyTests.cs +++ b/tests/MinimalLambda.SourceGenerators.UnitTests/VerifyTests/StaticMethodVerifyTests.cs @@ -53,7 +53,7 @@ public interface IService public static class HandlerFactory { public static string Handler( - [Event] string input, + [FromEvent] string input, ILambdaContext context, [FromKeyedServices("key")] IService service ) diff --git a/tests/MinimalLambda.Testing.UnitTests/Lambdas/MinimalLambda.Testing.UnitTests.DiLambda/Program.cs b/tests/MinimalLambda.Testing.UnitTests/Lambdas/MinimalLambda.Testing.UnitTests.DiLambda/Program.cs index 5cae4ce2..df3eea13 100644 --- a/tests/MinimalLambda.Testing.UnitTests/Lambdas/MinimalLambda.Testing.UnitTests.DiLambda/Program.cs +++ b/tests/MinimalLambda.Testing.UnitTests/Lambdas/MinimalLambda.Testing.UnitTests.DiLambda/Program.cs @@ -30,7 +30,7 @@ ); lambda.MapHandler( - ([Event] DiLambdaRequest diLambdaRequest, IService service, ILogger logger) => + ([FromEvent] DiLambdaRequest diLambdaRequest, IService service, ILogger logger) => { logger.LogInformation("Lambda handler"); return new DiLambdaResponse(service.GetMessage(diLambdaRequest.Name), DateTime.UtcNow); diff --git a/tests/MinimalLambda.Testing.UnitTests/Lambdas/MinimalLambda.Testing.UnitTests.NoResponseLambda/Program.cs b/tests/MinimalLambda.Testing.UnitTests/Lambdas/MinimalLambda.Testing.UnitTests.NoResponseLambda/Program.cs index 601f87cc..62200825 100644 --- a/tests/MinimalLambda.Testing.UnitTests/Lambdas/MinimalLambda.Testing.UnitTests.NoResponseLambda/Program.cs +++ b/tests/MinimalLambda.Testing.UnitTests/Lambdas/MinimalLambda.Testing.UnitTests.NoResponseLambda/Program.cs @@ -5,7 +5,7 @@ await using var lambda = builder.Build(); -lambda.MapHandler(([Event] NoResponseLambdaRequest request) => { }); +lambda.MapHandler(([FromEvent] NoResponseLambdaRequest request) => { }); await lambda.RunAsync(); diff --git a/tests/MinimalLambda.Testing.UnitTests/Lambdas/MinimalLambda.Testing.UnitTests.SimpleLambda/Program.cs b/tests/MinimalLambda.Testing.UnitTests/Lambdas/MinimalLambda.Testing.UnitTests.SimpleLambda/Program.cs index 75ae8144..b4f4ef37 100644 --- a/tests/MinimalLambda.Testing.UnitTests/Lambdas/MinimalLambda.Testing.UnitTests.SimpleLambda/Program.cs +++ b/tests/MinimalLambda.Testing.UnitTests/Lambdas/MinimalLambda.Testing.UnitTests.SimpleLambda/Program.cs @@ -6,7 +6,7 @@ await using var lambda = builder.Build(); lambda.MapHandler( - ([Event] string name) => + ([FromEvent] string name) => { if (string.IsNullOrWhiteSpace(name)) throw new Exception("Name is required");