✅ Generic DI in minimal APIs

I want register all the dependencies in one place for the endpoints. public static void MapAuthEndpoints(this WebApplication app) { var auth = app.MapGroup("auth"); auth.MapPost("login",LoginAsync); auth.MapGet("role/{id:Guid}",GetRoleAsync); } private static async Task<ApiResponse> LoginAsync(HttpContext context, LoginRequest loginRequest) { var response = await mediator.Send(new LoginCommand(loginRequest)); return new ApiResponse(requestPayload: requestPayload, statusCode: context.Response.StatusCode, response: response); } How can i inject IMediator once for all endpoints
24 Replies
cap5lut
cap5lut2y ago
afaik u just put the dependency in the parameter list
OneDeveloper
OneDeveloperOP2y ago
That i have to do for each endpoint
cap5lut
cap5lut2y ago
LoginAsync(HttpContext context, LoginRequest loginRequest, IMediator mediator)
OneDeveloper
OneDeveloperOP2y ago
Can we do it somewhere once like we were doing in Controller based method
cap5lut
cap5lut2y ago
not that im aware of
OneDeveloper
OneDeveloperOP2y ago
This one i have tried using (var scope = app.Services.CreateScope()) { var service = scope.ServiceProvider.GetRequiredService<AuthController>(); service.MapAuthEndpoints(app); } I tried like this But it gives IServiceProvider is disposed error { "statusCode": 500, "message": "An error Occurred", "requestDuration": "776 ms", "response": "Cannot access a disposed object.\r\nObject name: 'IServiceProvider'." }
cap5lut
cap5lut2y ago
where exactly are u executing this?
OneDeveloper
OneDeveloperOP2y ago
in program.cs
cap5lut
cap5lut2y ago
can u show the whole file?
OneDeveloper
OneDeveloperOP2y ago
public static void MapAuthEndpoints(this WebApplication app) { using var scope = app.Services.CreateScope(); IMediator mediator = scope.ServiceProvider.GetRequiredService<IMediator>(); RequestPayload requestPayload = scope.ServiceProvider.GetRequiredService<RequestPayload>(); var auth = app.MapGroup("auth"); auth.MapPost("login", async (HttpContext context, LoginRequest loginRequest) => { var response = await mediator.Send(new LoginCommand(loginRequest)); return new ApiResponse(requestPayload: requestPayload, statusCode: context.Response.StatusCode, response: response); }); auth.MapGet("role/{id:Guid}",GetRoleAsync); } Tried this. This one also gives the same error
cap5lut
cap5lut2y ago
show me how u register the services
OneDeveloper
OneDeveloperOP2y ago
using CQRS.Api; using CQRS.Api.Controllers; using CQRS.Application; using CQRS.Contracts; using CQRS.Infrastructure; var builder = WebApplication.CreateBuilder(args); var Services = builder.Services; #region Configure Services Services.AddControllers(); Services.AddScoped<RequestPayload>(); Services.AddApplication() .AddInfrastructure(builder.Configuration); #endregion var app = builder.Build(); #region Configure Global Exception Handling app.UseExceptionHandler("/error"); //app.UseExceptionHandler(ex => //{ // ex.Run(async context => // { // context.Response.StatusCode = StatusCodes.Status500InternalServerError; // context.Response.ContentType = "text/plain"; // Exception? exception = context.Features.Get<IExceptionHandlerFeature>()?.Error; // var requestPayload = context.RequestServices.GetRequiredService<RequestPayload>(); // var respose = new ApiResponse(requestPayload: requestPayload, // statusCode: StatusCodes.Status500InternalServerError, // message: "An unexpected error Occurred", // response: exception.Message); // await context.Response.WriteAsJsonAsync(respose); // }); //}); #endregion #region Configure Pipeline & Middleware app.UseMiddleware<Middleware>(); app.UseHttpsRedirection(); app.UseAuthentication(); app.UseAuthorization(); #endregion #region Configure COntrollers & Minimal APIs app.MapControllers(); //Minimal API for Register/Login app.MapAuthEndpoints(); //using (var scope = app.Services.CreateScope()) //{ // var service = scope.ServiceProvider.GetRequiredService<AuthController>(); // service.MapAuthEndpoints(app); //} #endregion app.Run(); This is my program.cs public static IServiceCollection AddApplication(this IServiceCollection services) { services.AddMediatR(config => config.RegisterServicesFromAssembly(typeof(DependencyInjection).Assembly)); //builder.Services.AddMediatR(config => config.RegisterServicesFromAssemblyContaining<Program>()); services.AddAutoMapper(typeof(DependencyInjection)); services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly()); services.AddScoped(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>)); return services; }
cap5lut
cap5lut2y ago
the problem lies basically there, u create a scope during configuration, basically before the web server runs. when u leave the method the scope will be disposed and all scoped and transient services as well
OneDeveloper
OneDeveloperOP2y ago
But this is in another static class I am using Extension Method
cap5lut
cap5lut2y ago
so basically either use minimal apis and inject all dependencies in the method or use the controllers
OneDeveloper
OneDeveloperOP2y ago
Okay Thanks!!
cap5lut
cap5lut2y ago
also for the next time please use $code blocks 😉
MODiX
MODiX2y ago
To post C# code type the following: ```cs // code here ``` Get an example by typing $codegif in chat If your code is too long, post it to: https://paste.mod.gg/
cap5lut
cap5lut2y ago
that way u get fancy syntax highlighting:
services.AddScoped(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>));
return services;
services.AddScoped(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>));
return services;
OneDeveloper
OneDeveloperOP2y ago
Cool Thanks for the tip
cap5lut
cap5lut2y ago
np and also if ur questions are answered please $close the thread to mark it as such, ofc only if it is
MODiX
MODiX2y ago
Use the /close command to mark a forum thread as answered
OneDeveloper
OneDeveloperOP2y ago
$codegif
Want results from more Discord servers?
Add your server