How to create a new instance of a dependency inject object

How to create a new instance of a dependency inject object

I decided to write this post after seeing it done wrong on a number of occasions and also not finding many great examples of how it should be done. Most articles of DI or IOC tend to focus on objects such as a logger being injected and then calling functions on that object.

Take for instance, this example in the Simple Injector documentation:

1using System;
2using System.Web.Mvc;
3
4public class UserController : Controller {
5 private readonly IUserRepository repository;
6 private readonly ILogger logger;
7
8 public UserController(IUserRepository repository, ILogger logger) {
9 this.repository = repository;
10 this.logger = logger;
11 }
12
13 [HttpGet]
14 public ActionResult Index(Guid id) {
15 this.logger.Log("Index called.");
16 IUser user = this.repository.GetById(id);
17 return this.View(user);
18 }
19}

Here we can see the implementation of IUserRepository and ILogger get passed in the constructor and are then used in the Index method.

However what would the example be if we wanted to create a new user and call the user repository to save it? Creating a new instance of IUser from our controller becomes an issue as we don't know what the implementation of IUser is.

The incorrect implementation I usually see is someone adding a reference to the implementation and just creating a new instance of it. A bit like this:

1public class UserController : Controller {
2 [HttpPost]
3 public ActionResult SaveUser(UserDetails newUserInfo) {
4
5 IUser user = new User;
6 user.FirstName = newUserInfo.FirstName;
7 user.LastName = newUserInfo.LastName;
8 this.repository.SaveUser(user);
9 return this.View(user);
10 }
11}

This will work, but fundamentally defeats the point of using dependency injection as we now have a dependency on the user objects specific implementation.

The solution I use is to add a factory method to our User Repository which takes care of creating a User object.

1public class UserRepository : IUserRepository {
2 public User CreateUser() {
3 return new User();
4 }
5}

Responsibility of creating the object now remains with its implementation and our controller no longer needs to have a reference to anything other than the interface.

1public class UserController : Controller {
2 [HttpPost]
3 public ActionResult SaveUser(UserDetails newUserInfo) {
4
5 IUser user = this.repository.CreateUser();
6 user.FirstName = newUserInfo.FirstName;
7 user.LastName = newUserInfo.LastName;
8 this.repository.SaveUser(user);
9 return this.View(user);
10 }
11}