Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid Services.AddScoped for every Use Case I have?

I'm trying to learn asp.net core (3.1) and clean architecture at the same time. The GitHub repository which I'm using as base is the https://github.com/ivanpaulovich/clean-architecture-manga and it's great.

The approaches used are pretty good and the repo owner answers you about the reasons of each approach. The problem I found is not about the approach now, but a better resolution. The webapi\dependencyinjection\ApplicationExtensions.cs class adds a scope for every use case he has:

        services.AddScoped<Application.Boundaries.CloseAccount.IUseCase, Application.UseCases.CloseAccount>();
        services.AddScoped<Application.Boundaries.Deposit.IUseCase, Application.UseCases.Deposit>();
        services.AddScoped<Application.Boundaries.GetAccountDetails.IUseCase, Application.UseCases.GetAccountDetails>();
        services.AddScoped<Application.Boundaries.GetCustomerDetails.IUseCase, Application.UseCases.GetCustomerDetails>();
        services.AddScoped<Application.Boundaries.Register.IUseCase, Application.UseCases.Register>();
        services.AddScoped<Application.Boundaries.Withdraw.IUseCase, Application.UseCases.Withdraw>();
        services.AddScoped<Application.Boundaries.Transfer.IUseCase, Application.UseCases.Transfer>();

There is any way to make it generic? To resolve the sample code with one line code only and all the use cases created after it will be injected?

like image 964
Leandro De Mello Fagundes Avatar asked Sep 18 '25 13:09

Leandro De Mello Fagundes


1 Answers

Explicitly registering dependencies can be seen as a benefit because you won’t get unwanted surprises later at runtime from seemingly “magic” registrations. This is especially true since your convention to register these types appears to be solely based on interface naming or namespaces. I would recommend you to add some stronger identifiers (e.g. common interfaces, or marker interfaces) if you want to utilize a convention-based registration there. Otherwise, it may seem better to list every single DI registration even if that may seem very verbose.

That being said, there are utilities that will help you with convention-based registrations. Of course, you could always write some code using reflection to register such things automatically. There is also this very useful utility package Scrutor that will register types based on conventions for you.

If each of the type only implements a single interface, then you could use the following scan to register the services as scoped services for their interfaces:

var type = typeof(Application.UseCases.CloseAccount);
services.Scan(scan => scan.FromAssembliesOf(type)
    .AddClasses(classes => classes.InExactNamespaceOf(type))
    .AsImplementedInterfaces()
    .WithScopedLifetime());
like image 60
poke Avatar answered Sep 21 '25 03:09

poke