Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for [AsParameters] attribute #133

Open
mikegaziotis opened this issue Jul 20, 2024 · 4 comments
Open

Add support for [AsParameters] attribute #133

mikegaziotis opened this issue Jul 20, 2024 · 4 comments

Comments

@mikegaziotis
Copy link

mikegaziotis commented Jul 20, 2024

Hi! First off, congrats, this a pretty cool library and I'm currently using it (with joy!) in production. I was wondering if it would be possible to add support for something like the [AsParameters] attribute that was added to AspNetCore from .net 7.0, to augment Minimal APIs. In Asp this attribute allows for grouping all request parameters into one request class/record/struct.

AspNetCore Example:

struct TodoItemRequest
{
    public int Id { get; set; }
    public string Description { get; set; }
}

app.MapPost("/api/todoitem", async ([AsParameters] TodoItemRequest request) =>
    Console.Writeline($"You posted item with Id: {request.Id}, and Description: {request.Description}");

You can see more details here

The advantage of being able to do that, is that along with the [FromServices] attribute, you will be able to have for every command delegate only two parameters. One parameter for dependency injecting all the services, and one for grouping all the arguments.

Example of how it could work

//program.cs
var services = new ServiceCollection();
services.AddLogging();
services.AddTransient<TestCommandHandler>();

using var serviceProvider = services.BuildServiceProvider();
ConsoleApp.ServiceProvider = serviceProvider;

var app = ConsoleApp.Create();

app.Add("test", async ([FromServices] TestCommandHandler commandHandler, 
        [AsParameters] TestCommandArgs args) => await commandHandler.Handle(args));

app.Run(args);

//in another file...

public record TestCommandArgs([Argument]string Param1, int? Param2) : ICommandArgs;

public class TestCommandHandler(ILogger<TestCommandHandler> logger) : ICommandHandler<TestCommandArgs>
{
    public async Task Handle(TestCommandArgs args)
    {
        logger.LogInformation(args.Param1);
        if (args.Param2.HasValue)
        {
            logger.LogInformation(args.Param2.ToString());
        }
    }
}

In the example above TestCommandHandler works as vehicle for injecting all necessary service dependency through its constructor. And TestCommandArgs is the vehicle for grouping all command args that become parameters, into a single record.

As you see in the example the TestCommandHandler and TestCommandArgs also implement some interfaces, name ICommandHandler and ICommandArgs. That's because another advantage of as [AsParameters] attribute is that it allows you to create one standard interface for all your command delegate handlers. Which can increase code readability, code writing speed (through IDE auto-completion) and also maintenance speed when refactoring. Here's some example interfaces for the above:

public interface ICommandHandler<in TCommandArgs> where TCommandArgs: ICommandArgs
{
    public Task Handle(TCommandArgs args);
}
public interface ICommandArgs;

This is by no means a necessity, but it would be a pretty cool feature to add. Thanks!

@neuecc
Copy link
Member

neuecc commented Jul 24, 2024

Thanks for the request.
The feature itself is good!
However, as a priority, it will be a while before I implement it myself.

@mikegaziotis
Copy link
Author

Understandable. I’ll give it a go and if I’m successful I’ll raise a PR if that’s ok with you?

@neuecc
Copy link
Member

neuecc commented Jul 25, 2024

Yes, it's welcome!

@Simonl9l
Copy link

Simonl9l commented Sep 4, 2024

With is approach - How does one specify an [Argument] vs. an option - today the [Argument] only support parameters, and would also need to be extended to Attributes (of the PoCo)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants