Reputation: 21211
I am trying to register a type like IRequestHandler1[GenericTestRequest
1[T]] which will be implemented by GenericTestRequestHandler`1[T] but I am currently getting an error from Windsor "Castle.MicroKernel.ComponentNotFoundException : No component for supporting the service " Is this type of operation supported? Or is it to far removed from the suppored register( Component.For(typeof( IList<>).ImplementedBy( typeof( List<> ) ) )
below is an example of a breaking test. //////////////////////////////////////////////////////
public interface IRequestHandler{}
public interface IRequestHandler<TRequest> : IRequestHandler where TRequest : Request{}
public class GenericTestRequest<T> : Request{}
public class GenericTestRequestHandler<T> : RequestHandler<GenericTestRequest<T>>{}
[TestFixture]
public class ComponentRegistrationTests{
[Test]
public void DoNotAutoRegisterGenericRequestHandler(){
var IOC = new Castle.Windsor.WindsorContainer();
var type = typeof( IRequestHandler<> ).MakeGenericType( typeof( GenericTestRequest<> ) );
IOC.Register( Component.For( type ).ImplementedBy( typeof( GenericTestRequestHandler<> ) ) );
var requestHandler = IoC.Container.Resolve( typeof(IRequestHandler<GenericTestRequest<String>>));
Assert.IsInstanceOf <IRequestHandler<GenericTestRequest<String>>>( requestHandler );
Assert.IsNotNull( requestHandler );
}
}
Upvotes: 0
Views: 1327
Reputation: 99730
I think the problem here is that the service type is not a generic type definition, while the implementation type is. The following tests all pass, which proves this:
[Test]
public void ServiceIsNotGenericTypeDefinition() {
var service = typeof(IRequestHandler<>).MakeGenericType(typeof(GenericTestRequest<>));
Assert.IsFalse(service.IsGenericTypeDefinition);
}
[Test]
public void ImplementationIsGenericTypeDefinition() {
var implementation = typeof (GenericTestRequestHandler<>);
Assert.IsTrue(implementation.IsGenericTypeDefinition);
}
[Test]
[ExpectedException(typeof(InvalidOperationException))]
public void FillOpenGenericType() {
var service = typeof(IRequestHandler<>).MakeGenericType(typeof(GenericTestRequest<>));
service.MakeGenericType(typeof (string));
}
This is because the actual open parameter type on the interface is the "inner" Type, and not the "resulting" type.
So this would be like registering a component with interface ICollection
(not the generic ICollection
!) and implementation type List<>
. When you ask Windsor for ICollection
, it doesn't know what type parameter to apply to the implementation type.
In your case it's even worse because you're asking for IRequestHandler<GenericTestRequest<String>>
which isn't really registered. (IRequestHandler<GenericTestRequest<>>
is)
Hope that was clear...
Upvotes: 4