How-To: Minimal IoC solution using AutoFac — C#

Dieri Ismail
3 min readJan 11, 2022

--

Despite the fact that the default .Net core IoC container has all the essential capabilities, it lacks many features, that I judge mandatory, for today’s projects. One of the best alternatives is AutoFac.

In this article, I will present a minimal IoC solution that fits with any .Net Core project type regardless of the architecture you are choosing.

Goal

We all had this sad experience when registering public components to the app IoC container; we register the components one by one. Often we find ourselves writing a bunch of repetitive registration lines(mainly for the typical <interface, implementation> components). We should always keep in mind to modify the registration method for every new public service to expose. What a boring and error-prone task we are always struggling with.

What I am offering here, is a solution that automates a big part of this task.

What comes next is a step-by-step description of the solution.

For the impatients, please see the link for the code of this solution.

Nuget Packages

We need the following packages:

PM> Install-Package Autofac
PM> Install-Package
Autofac.Extensions.DependencyInjection

Autofac Modules

Modules are a core part of the AutoFac framework. It gives us a lot of flexibility and a bunch of possibilities to cover more dependencies registration scenarios.

We can define as many Modules as we need all depending on our DI strategy.

In my case, I chose to define a per-layer module for more independent registration.

First, I created the abstract AssemblyScanModule. This module will scan the current assembly and try to find all the public interfaces exposed by the assembly and will add a new line, of type <public interface, its implementation>, to the IoC container. Most of the lines we used to write manually will now be performed automatically thanks to the AssemblyScanModule.

So whenever you need this scanning strategy, you only need to add a module that implements the AssemblyScanModule.

If you need some custom configuration(EF configuration, generic types, multiple implementations for a single interface, …), you can override the AssemblyScanModule Load method like below

Startup hosting configuration

In the solution that I provide, I am giving two front-end examples using the Asp.Net Core Razor Pages template, but the steps I will describe here are common to all the .net core templates.

First I would recommend creating an extension method for Modules registration step to keep things clean.

Here I am scanning only my solution assemblies MinimalIoC.*.dll, for fast and efficient scan, to search for concrete Module files and register them.

Please note, that for some cases the code I wrote to search for the assemblies will not work for some different reasons (iis deployments, …). Be ready to adapt it for your specific story.

.Net Core 6 minimal hosting

.Net core 6 comes with ‘minimal hosting’ thus apps go from two files, Program.cs and Startup.cs, to just one, Program.cs.

So to enable AutoFac modules registration, the Program.cs looks like the following

.Net Core classic hosting

For previous versions of the .Net core, the hosting is done using the two files Program.cs and the Startup.cs .

In the program.cs file, we add the AutoFacServiceProviderFactory

Next, in the Startup.cs we call the extension method to register the AutoFac Modules.

Why you can opt for this solution,

  • Configuration is done only once!
  • It covers the most common scenarios of IoC implementation,<interface, implementation> dependencies
  • It’s extendable for more complicated configurations, your code is more aligned to the open-closed principle.
  • Components registration is now done per layer, your code becomes more SRP.
  • Layers can keep the implementation of their public interfaces hidden to the other layers, your code becomes more respectful to the encapsulation principle
  • By choosing the Assembly scan, you can avoid writing many lines to register every single component. Moreover, the configuration you put in place does not change often!, your code becomes more KISS.
  • The main UI layer does not have to know about the other layers of your system to register the dependencies.
  • Adding configuration for a new layer is much simpler, you need to add a new Module file and that’s all.

I hope you enjoy it!

--

--

Dieri Ismail

Ismail is a confirmed fullstack .Net programmer with a solid background on software engineering. he is strong believer on craftmanship and pragmatism values.