DEV Community

loading...
Cover image for Dependency Injection, easy registration in .Net core

Dependency Injection, easy registration in .Net core

Ali Alp
“Take it easy” is nonsense , take it as hard as you can and don’t let it go :)
・2 min read

What if you could register your DI services inside your service interface just like this

[InjectThisServiceAs(ServiceLifetime.Transient)]
public interface IServiceA
{
    void Do();
}
Enter fullscreen mode Exit fullscreen mode

well you can :)

Install EasyDI package

dotnet add package EasyDI
Enter fullscreen mode Exit fullscreen mode

And then just add this line to your ConfigureService method of your Startup.cs like this

services.AddAnnotatedServices(typeof(Startup));
Enter fullscreen mode Exit fullscreen mode

and you are good to go. In every service interface by using the InjectThisServiceAs annotation and passing your desired service lifetime, your service will be automatically registered in the dotnet core DI engine, isn't it cool :)

checkout the source code here

install the Nuget package from here

Why EasyDI ?

1. To solve the forgotten service in DI registry

you only need to add the

services.AddAnnotatedServices(typeof(Startup));
Enter fullscreen mode Exit fullscreen mode

onetime and afterwards your job with the Startup.cs for typical service registering is done.
How many times have you run your .Net core application and then boom! you got an error message like this

System.InvalidOperationException: Unable to resolve service for type ... 
 at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, ...
Enter fullscreen mode Exit fullscreen mode

And after checking out your code you figured out that the reason was that you have forgot to register your service(s) to the DI engine. This can be so annoying sometimes considering that you have already coded your service interface and its implementation and even used it by constructor injection in your controller or another service

public interface IServiceA
{
    void Do();
}

public class ServiceA :IServiceA
{
    void Do(){
        // implementation 
    }
}

public class TestController : ControllerBase
{
    private readonly IServiceA _serviceA;

    public TestController(IServiceA serviceA)
    {
        _serviceA = serviceA;
    }
}
Enter fullscreen mode Exit fullscreen mode

And the only missing part of the puzzle was


public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        ...
        services.AddScoped<IServiceA, ServiceA>();
        ...
    }
}
Enter fullscreen mode Exit fullscreen mode

2. To solve the service registry hell issue

After your application begin to grow, you will need to add more and more services to your application to take care of the new functionalities. However, as you add more services to the application you need to register them in DI as well somewhere in the Startup.cs or an extension class. No matter how clean you try to be in terms of the folder structure and naming, after a while you end up having a class with hundreds of line like this

services.AddTransient<IServiceA, ServiceA>();
services.AddScoped<IServiceB, ServiceB>();
services.AddSingleton<IServiceC, ServiceC>();
services.AddScoped<IServiceD, ServiceD>();
services.AddScoped<IServiceE, ServiceE>();
services.AddScoped<IServiceF, ServiceF>();
services.AddScoped<IServiceH, ServiceH>();
services.AddScoped<IServiceI, ServiceI>();
services.AddScoped<IServiceJ, ServiceJ>();
.
.
.
.
Enter fullscreen mode Exit fullscreen mode

by using the EasyDI, you distribute this registration to each interface of your service, therefore you do not need to spend any effort to organize these registrations plus when you open your service interface you have a goof idea that what is the service life time of that service, isn't it cool :)

checkout the source code here

install the Nuget package from here

Discussion (4)

Collapse
fructuoso profile image
Víctor Fructuoso

I like this article, good job.
But I was thinking: Attributes dirty the code and add other dependencies, and in some cases we has many services to one interfaces or we need mock services in tests. With this package we lost control of DI.
Whats your opnion?

Collapse
wrldwzrd89 profile image
Eric Ahnell

This is going to make my life easier as an ASPNET Core developer, that’s for sure! I have already hit a smaller version of this issue in my app...

Collapse
alialp profile image
Ali Alp Author

glad to hear that :)

Collapse
programmerbyda1 profile image
ProgrammerByDay

Interesting idea