Learn how dependency injection mechanism has evolved from ASP.NET to ASP.NET Core.
Okay ! Since I’m writing blogs mostly on ASP.NET Core lately, you might be wondering why am I writing a blog on a topic which is already available in ASP.NET Core official documentation.
Well, in this post, I’m not only going to talk about how you can achieve DI (Dependency Injection) in .NET Core but will also discuss about DI itself (what, why and how). This article reflects how I actually learned (still learning) DI. So, if you don’t want to follow my approach or don’t want a deep dive into DI, then I would suggest you to follow the official link.
If you are reading this paragraph, then maybe you are interested in a deep dive into the wonderful world of DI with me. So, are you ready? I guess you are. Let’s get started!
An application is made of different components coupled together. Coupling is good but what about strict coupling? That’s definitely bad. According to the second principle of the very well-known software design principles (simply called SOLID), "Software entities (components/class/module/functions) should be open for extension, but closed for modifications (ca be achieved with abstract classes/interfaces)."
Since we need to make our application extensible over time, we need to make sure that different components in our application are loosely coupled together. DI is a way in which we can achieve loose coupling in our application.
On Enterprise level, we often work with n-tier applications. For our example, let’s assume that we have this 3-tier application.

It is basically a Web API application. So, all I did is I exposed some data over the client (presentation layer) using APIs. Here, we have AngularJS on the client-side (presentation layer). We have our API Controllers in the business layer and we have our Entity Framework database context to do the dirty works in the data access layer.
In this case, we really don’t have to worry about DI in the presentation layer because we can do DI in client side separately. Frameworks like AngularJS provide their own way of implementing DI, client-side. Notice that I said frameworks (AngularJS, EmberJS, BackboneJS), not libraries (jQuery, Knockout). You can use libraries and make your own framework where people can implement DI in your provided way.
I’m making things clear so that you can’t poke me later saying, “you didn’t do DI in the presentation layer”. DI is really just a concept and a technique to learn, upon learning, you can use the same concept and technique in any kind of application framework of your like. This can be either server side framework or client-side framework.
So, don’t mix things up.
Today, I’ll show you how you can achieve dependency in ASP.NET Core. So, that’s server-side. But before that, let’s see what is the current state of our application. Let’s take a look into the business layer and data access layer.
A snapshot from the data access layer would be (don’t try to understand the code.)
- public class TodoRepository
- {
- private readonly TodoContext _context = new TodoContext();
- public IEnumerable<Todo> GetAll()
- {
- return _context.Todos;
- }
- public void Add(Todo item)
- {
- _context.Todos.Add(item);
- _context.SaveChanges();
- }
- public Todo Find(int id)
- {
- Todo todo = _context.Todos.AsNoTracking().FirstOrDefault(t => t.Id == id);
- return todo;
- }
- public Todo Remove(int id)
- {
- Todo todo = _context.Todos.FirstOrDefault(t => t.Id == id);
- _context.Todos.Remove(todo);
- _context.SaveChanges();
- return todo;
- }
- public void Update(int id, Todo item)
- {
- Todo todo = _context.Todos.FirstOrDefault(t => t.Id == id);
- todo.Title = item.Title;
- todo.IsDone = item.IsDone;
- _context.SaveChanges();
- }
- }
- class TodoContext : DbContext
- {
- public TodoContext() : base("TodoDbConnectionString")
- {
- }
- public DbSet<Todo> Todos { get; set; }
- }
TodoDbConnectionString is the connection string name.
We have the API Controller in the business layer (middle layer). If you are still trying to understand the code, then don’t. We are here to learn DI not how to make an n-tier application.
- public class TodoController : ApiController
- {
- private readonly TodoRepository _todoRepository = new TodoRepository();
- // GET: api/Todo
- public IEnumerable<Todo> Get()
- {
- return _todoRepository.GetAll();
- }
- // GET: api/Todo/5
- public Todo Get(int id)
- {
- return _todoRepository.Find(id);
- }
- // POST: api/Todo
- public void Post([FromBody]Todo todo)
- {
- _todoRepository.Add(todo);
- }
- // PUT: api/Todo/5
- public void Put(int id, [FromBody]Todo todo)
- {
- _todoRepository.Update(id, todo);
- }
- // DELETE: api/Todo/5
- public void Delete(int id)
- {
- _todoRepository.Remove(id);
- }
- }
We will go to those individual classes and then replace the instantiations with the new types. But doing this will break the second rule of the SOLID design principle. (Here, not only we are making our application inextensible but we are also modifying it each time our requirement is changing).
Say for example, our client changed their requirement and now wants us to read and write comma separated data (CSV) from a file system instead of a database. Suppose, I’ve searched and downloaded a cool library that can work with CSV files. So, we have a CSV library configured and ready to talk with our CSV files in the data access layer.
- public class TodoCSVRepository
- {
- private readonly SomeCSVLibary _someCSVLibrary = new SomeCSVLibary();
- public IEnumerable<Todo> GetAll()
- {
- /* Use _someCSVLibrary library instance and get all the todo */
- }
- public void Add(Todo item)
- {
- /* Use _someCSVLibrary library instance to add a new todo */
- }
- public Todo Find(int id)
- {
- /* Use _someCSVLibrary library to find a todo by id */
- }
- public Todo Remove(int id)
- {
- /* Use _someCSVLibrary library to remove a todo by id */
- }
- public void Update(int id, Todo item)
- {
- /* Use _someCSVLibrary library to update a todo */
- }
- }
- private readonly TodoRepository _todoRepository = new TodoRepository();
- public interface ITodoRepository
- {
- void Add(Todo item);
- Todo Find(int id);
- IEnumerable<Todo> GetAll();
- Todo Remove(int id);
- void Update(int id, Todo item);
- }
TodoRepository.cs
- public class TodoRepository : ITodoRepository { ... }
- public class TodoCSVRepository : ITodoRepository { ... }
- private readonly ITodoRepository _todoRepository = new TodoRepository();
- private readonly ITodoRepository _todoRepository;
- public TodoController()
- {
- _todoRepository = new TodoRepository();
- }
- private readonly ITodoRepository _todoRepository;
- public TodoController(ITodoRepository todoRepository)
- {
- _todoRepository = todoRepository;
- }
This also follows the fifth principle (Dependency Inversion Principle) of SOLID design principles which states that, "High-level modules should not depend on low-level modules. Both should depend on abstractions."
Everything looks good but at this point, your program won’t run as you expected because it's expecting a instance of a repository type to be passed in the Controller. So, we can do some pure man’s DI here (passing an instance of an concrete repository type from the default constructor) ,
- private readonly ITodoRepository _todoRepository;
- public TodoController() : this(new TodoRepository())
- {
- }
- public TodoController(ITodoRepository todoRepository)
- {
- _todoRepository = todoRepository;
- }
- public class CompositionRoot : IHttpControllerActivator
- {
- public IHttpController Create(
- HttpRequestMessage request,
- HttpControllerDescriptor controllerDescriptor,
- Type controllerType)
- {
- if (controllerType == typeof(TodoController))
- return new TodoController(
- new TodoRepository());
- return null;
- }
- }
- GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator),new CompositionRoot());
That’s good since we have to deal with resolving tiny dependencies for this small project of ours. What if we have a large project where hundreds of dependencies are scattered around? In that cases, composition root won’t be a good idea. That is why in enterprise level, we use a well-known IoC (Inversion of Control) container to make our job easy. IoC containers can resolve dependencies recursively and they are also pretty much easy to configure. They allows us to work with dependency injection lifecycle easily.
There are many IoC containers available and most of them do the same things somewhat differently. Let’s use one of them in our current project. Let’s pick Autofac which has a great documentation online. Here is the link where you can know all about the Autofac integration related stuff with Web API projects,
Since we are just beginners wondering around the world of dependency injection, we will go slow and easy. The Autofac library for Web API projects is available to download to from NuGet.
Install-Package Autofac.WebApi2
I’ve downloaded it in my Techtalkers.WEB project. It is time to configure it. I’ve created a class in the App_Startfolder and added this method where I’ve configured Autofac like this.
- public class AutofacConfig
- {
- public static void RegisterAutofac()
- {
- var builder = new ContainerBuilder();
- var config = GlobalConfiguration.Configuration;
- builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
- builder.RegisterType<TodoRepository>().As<ITodoRepository>().InstancePerRequest();
- var container = builder.Build();
- config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
- }
- }
Next, we have to call the RegisterAutofac() from the Global.asax.cs. There, the Application_Start() is called every time the application is started. So, like the other registration stuff, I’ve registered the RegisterAutofac() method there.
- protected void Application_Start()
- {
- AreaRegistration.RegisterAllAreas();
- GlobalConfiguration.Configure(WebApiConfig.Register);
- FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
- RouteConfig.RegisterRoutes(RouteTable.Routes);
- AutofacConfig.RegisterAutofac();
- }
- public class TestTodoControlloer
- {
- [TestMethod]
- public void GetAll_ShouldReturnAllTodos()
- {
- // Arrange
- var mockRepository = new Mock<ITodoRepository>();
- mockRepository.Setup(x => x.GetAll())
- .Returns(new List<Todo>()
- {
- new Todo() {Id = 1, Title = "Test Item 1", IsDone = true},
- new Todo() {Id = 2, Title = "Test Item 2", IsDone = true},
- new Todo() {Id = 3, Title = "Test Item 3", IsDone = false}
- });
- var controller = new TodoController(mockRepository.Object);
- // Act
- var todoes = controller.Get();
- // Assert
- Assert.IsNotNull(todoes);
- Assert.AreEqual(3, todoes.Count());
- Assert.AreEqual(2, todoes.Count(t => t.IsDone));
- }
- }
Now that we have some get to go understanding on DI, we can make a tour to the wonderful world of .net core and see how DI is done there. .Net core by default provides some bare minimum functionality to do DI. But most of the time it’s enough for even big project that has hundreds of dependencies. For the time being .net core’s default IoC container only support construction injection.
So, just like we did with Autofac if you want to serve a concrete TodoRepository instance whenever ITodoRepository get caught in the scope, you would do something like this in the ConfigureServices()method,
- services.AddScoped<TodoRepository, ITodoRepository>();
The two other service lifetimes are Singleton and Transient. And they can be registered like above,
- services.AddSingleton<TodoRepository, ITodoRepository >();
- services.AddTransient<TodoRepository, ITodoRepository >();
In transient lifetime, new service instances are created per requests for all the parent and nested scopes.
If you dont feel happy with the built-in functionality, you can also add third part IoC containers. Autofac, by itself, can be used with .NET Core. You can have a good idea on how to integrate Autofac at this link.
You can learn more about dependecy injection in .net core from this official link.
So, that’s it. I guess now you are pretty much comfortable with dependency injection and its related terms. But before you think you are done, let me remind you again that these are very much beginner level articles. Also, I only talked about constructor injection. But there is also property injection, method injection, interface injection and etc. I’ll let you do the honor and explore them. Other than lifetime management, you can do a lot with Ioc containers, so there are lot of things to learn too. Now, go and get your feet wet.

Manav PandyaPosted Dec 30, 2016, 8:39 AM
Yahh thanks for sharing this code ...
Fiyaz HasanPosted Dec 30, 2016, 5:09 AM
Maybe this repository can help you - https://github.com/fiyazbinhasan/Polymer-With-ASP.NET-CORE-WEB-API/tree/master/src/Asp.Net.Core.With.Polymer.Starter
Manav PandyaPosted Dec 30, 2016, 4:47 AM
Do you have source code link for this demo
Manav PandyaPosted Dec 30, 2016, 4:46 AM
Thanks for sharing sir @fiyaz hasan ji