Dependency Injection

We’re not going to talk about whole SOLID extensively, maybe in future when there will be good time for it like this, but it’s sin to touch Dependency Injection without saying anything about 5th SOLID principle, Dependency Inversion, mind different name.

Dependency Inversion

Main point of Dependency Inversion is to decouple your code. It means that your modules should depend on abstractions (interface, abstract class etc), when you’re using implementation of class somewhere else you’re coupling yourself to one solution, using abstraction you can switch implementation whenever you want. And way to do this is to use Dependency Injection.

Dependency Injection

As I said earlier DI is way to implement Dependency Inversion. We start coding from creating abstraction i.e Interface then implementation for that interface. When we’re done we need to register interface and implementation in IoC (framework that will inject our dependencies) and that’s all. From that point whenever we’ll want to use our class we can pass interface to constructor and DI framework will inject registered implementation.

Thanks to that we’re not depending on implementation. If we would like to create similar functionality in different form we can reuse abstraction and create additional implementation. There’s more, we can even setup DI Container from text file and switch it at run time, it’s has its flaws, but still it’s possible, we’ll talk about it later in DI advanced post.

ASP.Net Core DI

In Asp.Net Core we have multiple possibilities. Net Core implements build in DI Container which is viable to use at the beginning, it can do basic stuff, but sooner or later we’ll need advanced DI Container for example Autofac.

Here we’ll compare both solutions and decide to which point it’s OK to use build in and when it’s good idea to switch to something more advanced.

Build-in IoC container

Provided by ASP.Net Core container is lightweight, very easy to use, but also very limited. You don’t have to do anything to start using it. But before we start, why would you like to use it?

It’s good idea if you want to keep things simple without additional dependencies, by limiting options build-in container is easier to use by inexperienced developers, to be honest it isn’t argument for using it, but I wanted to mention it. Best place to use it are small projects, because those wouldn’t need advanced DI features.

Usage

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddScoped<IStudentRepository, StudentRepository>();
    services.AddScoped<ICourseRepository, CourseRepository>();
    ...
}

You can register implementations one by one. Another way it to let IoC container scan assembly and register everything from there. Unfortunately you can’t do that using pure build-in container, you need to install Scrutor nuget package or implement method yourself. In my opinion it would be best time to start using more advanced IoC, unless you’d really want to drop any third party reference.

Autofac

Autofac is currently the mostly used DI container. I found it at the beginning of Net Core 2.0 where only few DI container could work with Net Core 2.0 from that point I’m still using it and I found Autofac good for everything I’ve been doing.

Setup

These are steps to start using Autofac:

  1. Install package Autofac.Extensions.DependencyInjection
  2. Change Program.cs
  3. Register implementations
// Program.cs

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
           .ConfigureServices(services => services.AddAutofac()) // <--
           .UseStartup<Startup>();
public void ConfigureContainer(ContainerBuilder builder)
{
    builder.RegisterType<StudentRepository>().As<IStudentRepository>();
    builder.RegisterType<CourseRepository>().As<ICourseRepository>();
}

As you can see it’s pretty much the same. That means you should follow only your needs. One thing for using Autofac is, that there are packages that have setup configuration using Autofac, so you can use them with just one extension method, we’ll talk about it later when we’ll use AutoMapper and Fluent Validation.

Basically I’m using Autofac in all of my projects, because it’s easy to setup, and every project may use some of its features sooner or later.

Service Lifetime

There is last important thing to cover. Lifetime of created services. Both tools need to specify how long created service will live until GC will clean it up. Autofac has more lifetime types, but build-in container has the most important, so still it’s not problem.

We can setup container so it will create single instance for every call or will create new instances of service every time something will need it. Here you can find great article with table that compares every lifetime option. You can check it, but you’ll only need to know that there is possibility to change how long service will live in your app, and if you’d need it, you’ll find best option for you.

Outro

I’ve presented only basics, as you can see using Autofac and build-in IoC container isn’t that different. That’s great, because we can switch from one to another without problems. On basic level there isn’t too much reasons to use Autofac. You can go with build-in IoC, but you should think about future.

If you’re going to extend your application maybe it’s good idea to start using advanced IoC container from the beginning. Of course, if you know how to set it up quickly. If you don’t know and you’d need more time to research topic then it’s better to go with something you know and switch to it later, I’ve done that with my project. In my opinion at the beginning it’s better to start working on application than learning things that you don’t need right away.

Leave a Reply