Как добавить зависимость, которую можно использовать в качестве параметра типа TImpl для Castle Windsor?
Я получил это исключение во время выполнения с определенным URL:
" Отсутствует зависимость. Компонент NRBQ.Web.Controllers.DeliveryController имеет зависимость от SeaStore.Data.Legacy.Interfaces.INRBQDeliveryRepository, которая не может быть разрешена. Убедитесь, что зависимость правильно зарегистрирована в контейнере как служба или предоставлена как встроенная аргумент ". ExceptionType: "Castle.MicroKernel.Resolvers.DependencyResolverException "
... поэтому я добавил этот код (на основе существующего кода, который работает) в класс IOC:
_container.Register
(Component
.For<INRBQDeliveryRepository>()
.ImplementedBy<DeliveryController>()
.LifeStyle.Transient);
В каком-то контексте:
private static Castle.Windsor.IWindsorContainer _container;
_container = new Castle.Windsor.WindsorContainer();
_container.AddFacility<Castle.Facilities.FactorySupport.FactorySupportFacility>();
. . .
_container.Register
(Component
.For<INRBQDeliveryRepository>()
.ImplementedBy<DeliveryController>()
.LifeStyle.Transient);
... но это даже не скомпилируется; Теперь я получаю:
Тип 'NRBQ.API.Controllers.DeliveryController' нельзя использовать в качестве параметра типа 'TImpl' в универсальном типе или методе 'Castle.MicroKernel.Registration.ComponentRegistration.ImplementedBy()'. Не существует неявного преобразования ссылок из NRBQ.API.Controllers.DeliveryController в SeaStore.Data.Legacy.Interfaces.INRBQDeliveryRepository.
Я знаю, что это, вероятно, немного загадочно (я, вероятно, опускаю некоторые важные детали в этом вопросе), но я не уверен, какие дополнительные подсказки я должен добавить.
ОБНОВИТЬ
В ответ на то, реализует ли DeliveryController INRBQDeliveryRepository: на самом деле, есть три вещи типа контроллера; пользовательский в NRBQ.Web:
public class DeliveryController : ApiController
{
private readonly INRBQDeliveryRepository _deliveryRepository;
public DeliveryController(INRBQDeliveryRepository deliveryRepository)
{
if (deliveryRepository == null)
{
throw new ArgumentNullException("DeliveriesController");
}
_deliveryRepository = deliveryRepository;
}
[Route("api/Deliveries/Count")]
public int GetCountOfDeliveryRecords()
{
return _deliveryRepository.GetCount();
}
. . .
... затем средний в NRBQ. Клиент:
namespace NRBQ.Client
{
public class RESTNRBQDelivery : INRBQDelivery
{
INRBQClientSettings NRBQClientSettings;
IRESTAPIClient RESTAPIClient;
public RESTNRBQDelivery(IRESTAPIClient RESTAPIClient, INRBQClientSettings NRBQClientSettings)
{
this.NRBQClientSettings = NRBQClientSettings;
this.RESTAPIClient = RESTAPIClient;
}
public RESTNRBQDelivery(IRESTAPIClient RESTAPIClient, INRBQClientSettings NRBQClientSettings, AuthenticationHeaderValue AuthHeader)
{
this.NRBQClientSettings = NRBQClientSettings;
this.RESTAPIClient = RESTAPIClient;
this.RESTAPIClient.AuthHeader = AuthHeader;
}
public int GetCount()
{
throw new NotImplementedException(); //TODO: Implement
}
.... и, наконец, тот, который действительно делает тяжелую работу за кулисами, в NRBQ.API:
namespace NRBQ.API.Controllers
{
public class DeliveryController : ApiController
{
ILogger Logger;
INRBQService NRBQService;
public DeliveryController(ILogger Logger, INRBQService NRBQService)
{
this.NRBQService = NRBQService;
this.Logger = Logger;
}
[HttpGet]
[Route("api/Deliveries/Count")]
public int GetCountOfDeliveryRecords()
{
//return _deliveryRepository.GetCount();
return NRBQService.GetNRBQEntity();
}
Последний звонок относится здесь:
public int GetNRBQEntity()
{
return 17; // Bogus val for now
}
Это все моя лучшая попытка скопировать существующий тестовый / примерный код, но я признаю, что моя голова плавает, и я не очень понимаю, что происходит (как и почему).
ОБНОВЛЕНИЕ 2
Хотя я уверен, что это все еще не совсем хот-дог Натана (кажется, что он гонится за всем творением, вызывая сначала эту абстракцию, затем ту, потом другую, потом обратно к первому, потом другому, потом обратно ко второму и т. д. и т. д. до бесконечности и до тошноты (Advillium), добавив следующее:
container.Register
(Component
.For<INRBQDelivery>()
.ImplementedBy<RESTNRBQDelivery>()
.LifeStyle.Transient);
...в контексте:
public class NRBQClientInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register
(Component
.For<SeaStore.Common.HTTP.IRESTAPIClient>()
.ImplementedBy<SeaStore.Common.HTTP.WebAPIClient>()
.LifeStyle.Transient);
container.Register
(Component
.For<INRBQClient>()
.ImplementedBy<RESTNRBQClient>()
.LifeStyle.Transient);
container.Register
(Component
.For<INRBQDelivery>()
.ImplementedBy<RESTNRBQDelivery>()
.LifeStyle.Transient);
}
}
... избавился от сообщения об ошибке и вернул фальшивый результат, который я ожидал (или, скорее, надеялся, что не ожидал).
1 ответ
В вашем модуле IWindsorInstaller зарегистрируйте интерфейс и его реализатор:
container.Register
(Component
.For<INRBQDelivery>()
.ImplementedBy<RESTNRBQDelivery>()
.LifeStyle.Transient);