Instead of injecting the entire DI container into your classes, you should only enter dependent ones .
Your UserController requires a DB adapter (call this IDBAdapter interface). In C #, it might look like this:
public class UserController { private readonly IDBAdapter db; public UserController(IDBAdapter db) { if (db == null) { throw new ArgumentNullException("db"); } this.db = db; } public void DetailsAction() { var model = new UserModel(this.db); model.GetDetails(12345); } }
In this case, we introduce the dependency in the UserModel. In most cases, however, I would be inclined to regard it as a DI smell if the UserController only accepts the dependency in order to pass it, so a better approach might be for the UserController to depend on an abstract Factory like this:
public interface IUserModelFactory { UserModel Create(); }
In this embodiment, the UserController might look like this:
public class UserController { private readonly IUserModelFactory factory; public UserController(IUserModelFactory factory) { if (factory == null) { throw new ArgumentNullException("factory"); } this.factory = factory; } public void DetailsAction() { var model = this.factory.Create(); model.GetDetails(12345); } }
and you can define a specific UserModelFactory that takes a dependency on IDBAdapter:
public class UserModelFactory : IUserModelFactory { private readonly IDBAdapter db; public UserModelFactory(IDBAdapter db) { if (db == null) { throw new ArgumentNullException("db"); } this.db = db; } public UserModel Create() { return new UserModel(this.db); } }
This gives you a better separation of concerns .
If you need more than one dependency, you simply enter them through the constructor. When you start getting too much, this is a sign that you are violating the principle of single responsibility , and this is the time for refactoring for aggregated services .
Mark seemann
source share