У меня интерфейс называется 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, даже если вы изменили только Contexts Y. Но да, вы знаете, что вы только Yне изменились X, так что SomeClassвсе в порядке. Но написание хорошего кода - это не то, что вы знаете, а то, что знает новый сотрудник, когда он смотрит на ваш код в первый раз.