在温莎城堡中使用泛型参数解析泛型

发布于 2024-08-10 06:01:43 字数 1329 浏览 10 评论 0 原文

我正在尝试注册类似 IRequestHandler1[GenericTestRequest1[T]] 的类型,该类型将由 GenericTestRequestHandler`1[T] 实现,但我目前从 Windsor 收到错误“Castle.MicroKernel.ComponentNotFoundException” :没有支持该服务的组件“是否支持这种类型的操作?或者它是否远离支持的寄存器( Component.For(typeof( IList<>).ImplementedBy( typeof( List<> ) ) )

下面是破坏测试的示例。 /////////////////////////////////////////////////////////// ////

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 );
}
}

I am trying to register a type like IRequestHandler1[GenericTestRequest1[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 );
}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

在你怀里撒娇 2024-08-17 06:01:43

我认为这里的问题是服务类型不是泛型类型定义,而实现类型。下面的测试全部通过,证明了这一点:

[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));
}

这是因为接口上实际开放的参数类型是“inner”类型,而不是“result”类型。

因此,这就像使用接口 ICollection(不是通用 ICollection!)和实现类型 List 注册组件。当您向 Windsor 请求 ICollection 时,它不知道要应用于实现类型的类型参数。

在您的情况下,情况更糟,因为您要求的 IRequestHandler> 并未真正注册。 (IRequestHandler>

希望这是清楚的...

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...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文