【问题标题】:Castle Windsor resolve array of generic interfacesCastle Windsor 解析通用接口数组
【发布时间】:2014-08-18 15:41:07
【问题描述】:

我有一个程序集,其中包含相同通用接口的一定数量的实现。 我在 Windsor 中使用以下注册方式一次性注册了所有这些:

Types
   .FromAssembly(Assembly.GetExecutingAssembly())
   .BasedOn(typeof(IQuery<,>))

现在我想获取所有已注册实现的数组,但如果我尝试这个 Castle 炸弹:

container.ResolveAll(typeof (IQuery<,>))

为什么?

【问题讨论】:

  • 有什么例外?
  • 那么期望是这个接口实现的一个数组,如果我在运行时通过调试检查容器,它实际上是一个数组。但是,如果我尝试使用通用接口来解决所有问题,城堡会抛出一个异常,说它无法解析通用接口数组
  • 您无法解析开放的泛型类型,因为 Windsor 不知道要为您创建什么。您必须指定一个封闭的泛型类型,例如container.ResolveAll(typeof(IQuery&lt;int, double&gt;))

标签: c# generics castle-windsor


【解决方案1】:

它不起作用,因为您的服务被注册为具体类型的实现。将WithService.FromInterface() 子句添加到您的注册代码中,将其注册为接口抽象。 IMO 它也不起作用(使用开放的泛型解析)。

【讨论】:

    【解决方案2】:

    @Steven 是对的,在不知道它们嵌入什么类型的情况下无法解析泛型类型。但是有两种方法可以回避这个问题

    您有一个可能的输入和输出类型的封闭列表,您可以对其进行迭代以解析所有特定组合

    for var Type1 in PossibleTypes1
        for var Type2 in PossibleTypes2
            var list = container.ResolveAll(typeof(IQuery<,>).MakeGenericType(Type1, Type2)
    

    这不是很优雅,但您可以获得所有查询。不过我想提出第二种选择。

    如果您想解决所有查询,您必须有一个您想调用它们的操作,或者您想获取一些信息。如果是这样,那么此操作或信息应该存在于您的通用接口继承自的基本非通用接口中。假设您想获取操作名称,您可以执行以下操作:

    public interface IBaseQuery {
        string getOperationName(); // your common operation 
    }
    
    public interface IQuery<In, Out>: IBaseQuery {
    }
    

    然后,您将针对所有接口注册您的 IQuery 实现并解析 IBaseQuery 以调用所有查询的通用实现。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-06
      • 1970-01-01
      • 2016-02-26
      • 2012-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多