I created few projects in my solution. I have models, services, tests and webApi project. I added LoginController which uses Services, but it uses it by interfaces. I need to use dependency injection to resolve it for me. I decided to add Autofac. It is IoC container which allow us to register all types and it’s implementations, to inject specific types for us. In the last year I wrote post how to add Autofac to ASP.NET MVC app, but post is in Polish and adding Autofac to .NET Core app is slighty different than the last time.
First step to add Autofac to our project is to download nuget package Autofac.Extensions.DependencyInjection.
Next step is to register all types from assemblies. We need to do it for each assembly (install Autofac too). For example I have ELP.Model, ELP.Service, ELP.WebApi projects and I want to register all types from them. To do it let’s start from ELP.Service project. I prefer to add new interface to it. Just empty interface to determine assembly.
1 2 3 |
public interface IDetermineServicesAssembly { } |
Add also new class derived from Autofac.Module class and override Load method.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
using Autofac; using System.Reflection; namespace ELP.Service { public class ServiceModule : Autofac.Module { protected override void Load(ContainerBuilder builder) { base.Load(builder); builder.RegisterAssemblyTypes(typeof(IDetermineServicesAssembly).GetTypeInfo().Assembly).AsImplementedInterfaces(); } } } |
As you see the interface is only to get type info from it to get all assemblies and register it in the container. We need to repeat these steps for each project (in my case ELP.Model, ELP.WebApi). This method is very helpful, because every type will be registered automatically without our attention. When we add new interface and class that implements it, no action is required. Autofac does all for us!
Ok if we have modules, it’s time to modify Startup class a little bit.
Add new property ApplicationContainer of IContainer type. Then Create Container builder in ConfigureServices method and register all modules in it, then build and return result in ApplicationContainer. Take a look at my Startup class below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
using System; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using ELP.Model; using Autofac; using Autofac.Extensions.DependencyInjection; using ELP.Service; using Microsoft.EntityFrameworkCore; using ELP.Model.Entities; using ELP.WebApi.Models; namespace ELP.WebApi { public class Startup { public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) .AddEnvironmentVariables(); Configuration = builder.Build(); } public IContainer ApplicationContainer { get; private set; } public IConfigurationRoot Configuration { get; } public IServiceProvider ConfigureServices(IServiceCollection services) { services.AddMvc(); var connectionString = Configuration["secretConString"]; services.AddDbContext<ELPContext>(o => o.UseSqlServer(connectionString)); var builder = new ContainerBuilder(); builder.RegisterModule<ModelModule>(); builder.RegisterModule<ServiceModule>(); builder.RegisterModule<WebApiModule>(); builder.Populate(services); ApplicationContainer = builder.Build(); return new AutofacServiceProvider(ApplicationContainer); } public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug(); app.UseMvc(); } } } |
That’s it. You can ask what if I have few types that implements one interface? How Autofac handles it? It registers the newest one, but maybe there will be a situation when you want to register specific type, then you can do it like this
1 |
builder.RegisterType<MyType>().As<IMyType>(); |
If you want to use Autofac in you applications I recommend you to take a look at the documentation, where you can read more about it.
One comment
Comments are closed.