【问题标题】:Exception when resolving generically typed concrete class from non-generic interface从非泛型接口解析泛型类型的具体类时出现异常
【发布时间】:2013-06-14 00:46:34
【问题描述】:

背景

我有一个非泛型接口 IInputEventProvider,它由具体类 InputEventProvider<TState, TInputEvent> 实现。

在我的安装程序中,我使用不同的泛型类型参数注册了四次具体类型,如下所示:

.Register(
    Component.For<IInputEventProvider>()
        .ImplementedBy<InputEventProvider<KeyboardState, KeyboardEvent>>(),
    Component.For<IInputEventProvider>()
        .ImplementedBy<InputEventProvider<MouseState, MouseButtonEvent>>(),
    Component.For<IInputEventProvider>()
        .ImplementedBy<InputEventProvider<MouseState, MouseMoveEvent>>(),
    Component.For<IInputEventProvider>()
        .ImplementedBy<InputEventProvider<MouseState, ScrollWheelEvent>>()
)

我还根据它们的接口对我的程序集中的所有类进行基于约定的注册:

.Register(
    Classes.FromAssemblyContaining<MainClass>()
        .Pick()
        .WithServiceAllInterfaces()
)

最后,在我的一个类中,我依赖于 IEnumerable&lt;IInputEventProvider&gt;,它应该返回我的四个注册类型实例。

问题

在我的作文根目录下解析时,出现以下异常:

请求的类型 Exuinoq.Core.Input.IInputEventProvider 有 0 个泛型 参数,而组件实现类型 Exuinoq.Core.Input.InputEventProvider`2[TState,TInputEvent] 需要 2.

这是因为安装程序中基于约定的注册已经选择了泛型具体类并将其注册为泛型类型,然后无法解析。

问题

避免这种情况并防止它在未来发生在其他班级的最佳方法是什么?该例外提供以下建议:

您可以指示 Windsor 应该使用哪种类型来关闭它 通过提供实现的通用组件 IGenericImplementationMatchingStrategy。

但是,我认为这只适用于您希望注册一个 single 类型的情况,而不是四种不同的类型。不过我可能是错的!

目前我已经使用了这种解决方法,但它几乎不可持续:

.Register(
    Classes.FromAssemblyContaining<MyClass>()
        .Where(t => !typeof(IInputEventProvider).IsAssignableFrom(t))
        .WithServiceAllInterfaces()
)

【问题讨论】:

  • 例外与您的四个显式注册的组件无关。您的其他注册很可能会再次以开放通用的方式学习该课程。您可以通过查看所有服务诊断来验证它
  • 是的,这就是我所说的“这是因为安装程序中基于约定的注册已经选择了泛型具体类并将其注册为泛型类型,然后无法解析”。我知道原因,我想知道解决方法:)
  • 解决方法很简单,用.Pick()代替.Where(somethingToFilterUnwantedTypesOut)
  • 这有点像“如何通过 3 个简单的步骤飞向月球”的经典描述......我知道 .Where() 运算符(显然 - 我在我的问题中提到了它)。我想知道的是somethingToFilterUnwantedTypesOut 的最佳实现或防止这种情况发生的等效方法。
  • 这取决于您想要防止发生什么。这种特殊类型?任何通用类型?您在更新的答案中得到的答案将在这种情况下完成工作。如果您只有这一种类型作为例外,那就太好了。

标签: c# inversion-of-control castle-windsor ioc-container


【解决方案1】:

一种解决方案是使用诸如[RegisterWith(Type t, Type t2)] 之类的属性标记所有此类具体类 - 但是建议将与容器相关的代码远离其他所有内容,因此我希望尽可能避免这种情况。我确实更喜欢这种解决方案,而不是硬编码容器中不需要的类型 - 它比配置更惯例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多