Правильный способ внедрения в базовый контроллер без перехода от наследования - PullRequest
1 голос
/ 20 мая 2019

У меня есть контроллер, похожий на этот.

public SomeController : Controller
{
  private readonly InjectableIntoEveryController _thing;
  public SomeController(InjectableIntoEveryController thing, ...) { ... }
}

Естественно, разработчик во мне хочет переместить вещь , то есть InjectableIntoEveryController , на базовый контроллери избегайте явных и пропускаемых инъекций.Поэтому я создаю следующее.

public BaseController : Controller
{
  private readonly InjectableIntoEveryController _thing;
  public BaseController(InjectableIntoEveryController thing, ...) { ... }
}

public SomeController : BaseController
{
  public SomeController(...) { ... }
}

Это не компилируется, потому что в базовом классе нет конструктора без параметров.Однако, если мы добавим один из них, как показано ниже, инъекции не произойдет, что не соответствует цели.

public BaseController : Controller
{
  private readonly InjectableIntoEveryController _thing;
  public BaseController() { ... }
  public BaseController(InjectableIntoEveryController thing, ...) { ... }
}

Единственный найденный мной способ заставить его летать - это передать вещь , используя base (...) , но для этого требуетсябыть введен, что противоречит цели всего рефакторинга.

public SomeController : BaseController
{
  public SomeController(InjectableIntoEveryController thing, ...)
  :base(thing) { ... }
}

Есть ли лучший способ гарантировать, что базовый контроллер получает инъецированные вещи, как я бы этого хотел, без явной передачи их от наследующего

1 Ответ

3 голосов
/ 20 мая 2019

Один из простых способов достижения цели - не указывать каждую зависимость каждый раз, - выгрузить ваши зависимости в класс контейнера и затем внедрить , что , во все ваши контроллеры:

public class Dependencies : IDependencies
{
     public Dependencies(IDependency1 d1, IDependency2 d2, <etc>) 
     {
          this.d1 = d1;
          this.d2 = d2;
          <etc>...
     }
}

Теперь в ваших контроллерах вы можете просто внедрить этот класс.

public SomeController 
{
     public SomeController(IDependencies d) { 
         this.d = d; 
     }
}

Его подпись никогда не изменится, даже если вам придется добавлять / удалять зависимости, поэтому все ваши контроллеры могут получить доступ к своим общим зависимостям без необходимости изменять свои подписи каждый раз, когда изменяются ваши зависимости.

Я согласен с комментариями, хотя: если это решение вашей проблемы, то вы, возможно, захотите выяснить, почему один класс имеет так много зависимостей (или почему так много классов имеют одинаковый список из них) , Хотя я определенно могу понять, что меня ограничивают обстоятельства (то есть я сам использовал это решение)!

...