У меня интерфейс называется IContext
. Для целей этого не имеет значения, что он делает, за исключением следующего:
T GetService<T>();
Этот метод просматривает текущий DI-контейнер приложения и пытается разрешить зависимость. Я думаю, что он довольно стандартный.
В моем приложении ASP.NET MVC мой конструктор выглядит следующим образом.
protected MyControllerBase(IContext ctx)
{
TheContext = ctx;
SomeService = ctx.GetService<ISomeService>();
AnotherService = ctx.GetService<IAnotherService>();
}
Поэтому вместо того, чтобы добавлять несколько параметров в конструктор для каждого сервиса (потому что это будет очень раздражающим и трудоемким для разработчиков, расширяющих приложение), я использую этот метод для получения сервисов.
Теперь он чувствует себя не так . Однако, способ, которым я в настоящее время оправдываю это в своей голове, состоит в следующем - я могу издеваться над этим .
Я могу. Нетрудно создать макет IContext
для тестирования контроллера. Я должен был бы в любом случае:
public class MyMockContext : IContext
{
public T GetService<T>()
{
if (typeof(T) == typeof(ISomeService))
{
// return another mock, or concrete etc etc
}
// etc etc
}
}
Но, как я уже сказал, это неправильно. Любые мысли / оскорбления приветствуются.
public SomeClass(Context c)
. Этот код вполне понятен, не так ли? В нем говорится, that SomeClass
зависит от Context
. Эээ, но подождите, это не так! Он зависит только от зависимости, которую X
он получает из Context. Это означает, что каждый раз, когда вы вносите изменения, Context
они могут сломаться SomeObject
, даже если вы изменили только Context
s Y
. Но да, вы знаете, что вы только Y
не изменились X
, так что SomeClass
все в порядке. Но написание хорошего кода - это не то, что вы знаете, а то, что знает новый сотрудник, когда он смотрит на ваш код в первый раз.