0

Здесь я использую каркас DI (Ninject), и он отлично работает. Но одна из проблем заключается в том, что у меня есть базовый класс с единственным конструктором, который реализует реализацию интерфейса.Как использовать инъекцию зависимостей для унаследованного класса?

public class BaseApiController : ApiController 
{ 
    readonly IAccessService _accessService; 
    public BaseApiController(IAccessService accessService) 
    { 
     this._accessService = accessService; 
    } 
} 

Когда я наследовать от этого базового класса для всех других контроллеров, которые имеют конструктор, которые берут реализацию своих собственных интерфейсов. Я получаю ошибку «BaseApiController» не содержит конструктор, который принимает 0 аргументов. Хорошо, я это понял. Производный класс

public class DiscoverController : BaseApiController 
{ 
    readonly IDiscoverService _discoverService; 
    readonly IAccessService _accessService; 

    public DiscoverController(IDiscoverService discoverService,IAccessService accessService) 
    { 
     _accessService = accessService; 
     _discoverService = discoverService; 
    } 
} 

Как я мог бы сделать это без изменения производного класса CTOR принять аналогичный параметр и передать это значение на базовой CTOR, я был бы признателен, если бы вы предложить лучший способ справиться с этим?

ответ

1

Try модифицирование производного конструктора, чтобы он передать аргумент базового класса:

public class DiscoverController : BaseApiController 
{ 
    readonly IDiscoverService _discoverService; 
    readonly IAccessService _accessService; 

    public DiscoverController(IDiscoverService discoverService,IAccessService accessService) : base(accessService) 
    { 
     _discoverService = discoverService; 
    } 
} 
4

Как сказал @Christian, ошибка ошибка компилятора C#, потому что вам придется пройти через зависимость.

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

То, что вы делаете неправильно, что вы:

  • Использование наследования вместо композиции и
  • использовать базовый класс для применения межотраслевых проблем (которые будут являться нарушением как Single Responsibility Principle и Open/Closed Principle когда вы добавите вторую сквозную проблему в этот базовый класс).

Вы используете этот IAccessService в базовом классе, возможно, для выполнения определенных проверок безопасности. Вместо использования базовых классов существуют лучшие методы. Общее решение - использовать декораторы, но это не работает с Web API. Вместо этого с помощью Web API вы можете использовать DelegateHandlers и добавлять их в конвейер. Такой обработчик действует как декоратор и позволяет прозрачно применять сквозные проблемы, такие как безопасность.

Смежные вопросы