Вместо того, чтобы вставлять весь DI-контейнер в ваши классы, вы должны внедрить только те зависимости , которые вам нужны.
Вашему UserController требуется адаптер БД (назовем этот интерфейс IDBAdapter). В C # это может выглядеть так:
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);
}
}
В этом случае мы вводим зависимость в UserModel. Однако в большинстве случаев я склонен считать это запахом DI, если UserController принимает только зависимость для его передачи, поэтому для UserController лучше использовать зависимость от абстрактной фабрики, как этот:
public interface IUserModelFactory
{
UserModel Create();
}
В этом варианте UserController может выглядеть следующим образом:
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);
}
}
и вы можете определить конкретный UserModelFactory, который принимает зависимость от 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);
}
}
Это дает вам лучшее разделение интересов .
Если вам нужно более одной зависимости, вы просто вводите их через конструктор. Когда вы начинаете получать слишком много, это признак того, что вы нарушаете Принцип единой ответственности , и пришло время реорганизовать агрегированные услуги .