问题
I was getting this runtime exception with a particular URL:
"Missing dependency. Component NRBQ.Web.Controllers.DeliveryController has a dependency on SeaStore.Data.Legacy.Interfaces.INRBQDeliveryRepository, which could not be resolved. Make sure the dependency is correctly registered in the container as a service, or provided as inline argument." ExceptionType: "Castle.MicroKernel.Resolvers.DependencyResolverException"
...so I added this code (based on existing code that works) to the IOC class:
_container.Register
(Component
.For<INRBQDeliveryRepository>()
.ImplementedBy<DeliveryController>()
.LifeStyle.Transient);
In some context:
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);
...but that won't even compile; I now get:
The type 'NRBQ.API.Controllers.DeliveryController' cannot be used as type parameter 'TImpl' in the generic type or method 'Castle.MicroKernel.Registration.ComponentRegistration.ImplementedBy()'. There is no implicit reference conversion from 'NRBQ.API.Controllers.DeliveryController' to 'SeaStore.Data.Legacy.Interfaces.INRBQDeliveryRepository'.
I know this is probably a bit myseterious (I'm probably omitting some important details in this question), but I'm not sure what additional clues I should add.
UPDATE
In response to whether DeliveryController implements INRBQDeliveryRepository: Actually, there are three controller-type things; a user-facing one in 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();
}
. . .
...then a middle one in NRBQ.Client:
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
}
....and finally the one that really does the behind-the-scenes heavy lifting, in 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();
}
That last call refers to here:
public int GetNRBQEntity()
{
return 17; // Bogus val for now
}
This all is my best attempt at copying existing test/sample code, but I admit that my head is swimming and I don't really grok what's happening (how and why).
UPDATE 2
Although I'm pretty sure it's still not quite a Nathan's hot dog (it seems to chase itself all over creation, calling first this abstraction, then that one, then another, then back to the first, then another, then back to the second, etc. etc. ad infinitum ad nauseum advillium), adding this:
container.Register
(Component
.For<INRBQDelivery>()
.ImplementedBy<RESTNRBQDelivery>()
.LifeStyle.Transient);
...in context:
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);
}
}
...got rid of the err msg and returned the fake result I was expecting (or, rather, hoping for, not really expecting).
回答1:
In your IWindsorInstaller unit, register the interface and its implementer:
container.Register
(Component
.For<INRBQDelivery>()
.ImplementedBy<RESTNRBQDelivery>()
.LifeStyle.Transient);
来源:https://stackoverflow.com/questions/24375991/how-can-i-add-a-dependency-that-can-be-used-as-type-parameter-timpl-for-castle