【问题标题】:Structuremap returning wrong instance for open generic type?Structuremap为开放的泛型类型返回错误的实例?
【发布时间】:2016-02-26 13:07:36
【问题描述】:

我正在尝试使用带有开放泛型的结构图在运行时获取事件处理程序的实例,我正在使用基于开放泛型的配置

     // #1 Configuration
         scan.ConnectImplementationsToTypesClosing(typeof(IHandle<>));
// #2 Actual class
      public class EventHandlerClass : 
            IHandle<MyEvent>,
            IHandle<AnotherEvent>,
            IHandle<ThirdEvent>,
        {
             void IHandle<MyEvent>.Handle(MyEvent args)
            {

            }
             void IHandle<AnotherEvent>.Handle(AnotherEvent args)
            {

            }
             void IHandle<ThirdEvent>.Handle(ThirdEvent args)
            {

            }

        }

我的代码适用于我通过构造函数注入请求依赖的情况,这样工作正常。

public MyClass(IHandle<MyEvent>[] alleventHandlers)
{

}

但是在我的一种情况下,我需要在运行时获取依赖项。 下面是我正在使用的代码

 // Code
 Type t = typeof(IHandle<>);
 MyEvent m = new MyEvent();
 var generic = t.MakeGenericType(m.GetType());
 dynamic instances = nestedContainer.GetAllInstances(genType) as IEnumerable;

 foreach( dynamic inst in instances)
 {
     inst.Handle(m)

 }

我收到以下错误。 {"'MyNameSpace.EventHandlerClass.Handle(MyNameSpace.Events.ThirdEvent)' 的最佳重载方法匹配有一些无效参数"}

GetAllInstances 似乎以某种方式返回了一个 EventHandlerClass 对象,其中一个 Handle 方法期望 ThirdEvent 事件,尽管我用正确的类型调用了 GetAllInstances。

这是一个错误吗?还是我配置有误?

【问题讨论】:

  • 这可能不是 StructureMap 的问题,而是动态调用如何工作的问题。如果使用反射调用Handle 方法会发生什么?即,在inst 上显式查找名为Handle 并采用m.GetType() 类型参数的方法。
  • @YacoubMassad :反射也一样,我实际上可以看到反射方法具有 ThirldEvent 的句柄方法。 GetAllInstances 从我在反射中看到的返回错误的对象
  • 您是否有理由显式地而不是隐式地实现接口?尝试隐式实现它们。

标签: c# structuremap open-generics


【解决方案1】:

动态变量只能访问类型方法(通常是公共的,但基于上下文)。它无权访问显式实现的接口方法。调用显式接口实现的唯一方法是将对象强制转换为接口。

所以你有两个选择,要么 a) 按照@Yacoub 的建议隐式实现接口,要么 b) 使用反射来调用方法。

foreach(dynamic inst in instances)
{
     Type type = inst.GetType();
     Type interfaceType = type.GetInterfaces().Single(t => t == generic);
     interfaceType.GetMethod("Handle").Invoke(inst, new object[] { m });
}

【讨论】:

  • 感谢您的解释,我最终使用了您的代码的变体来调用句柄方法。不能真正使用显式方法,因为它在一些遗留代码中进行了大量代码更改。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多