2

我试图在运行时调用一个通用接口方法,但是在查找类型信息时似乎找到了 IDomainEventSubscriber 而不是传递的正确类型。

抛出运行时错误:Object does not match target type.

检查我看到的 handlerInstance 类型的值是typeof(TestEventHandler),并methodInfo{System.Reflection.MethodBase}显示{Void HandleEvent(System.Object)}

所以它被设置为 System.Object 的方法类型,而不是实际类型(例如,在我们调用的情况下为 TestEvent Dispatch(new TestEvent());

是否有可能获得正确的实现,以便我可以在运行时调用接口成员?

public interface IDomainEventSubscriber<T>
{
    void HandleEvent(T domainEvent);
}

class TestEventHandler : IDomainEventSubscriber<TestEvent>
{
    public void HandleEvent(TestEvent domainEvent)
    {
    }
}

// some service that dispatches events
void Dispatch<T>(T eventToPublish) where T : class
{
    Type handlerType = map.GetHandlersForType(eventToPublish.GetType());
    // a valid object instance is returned from my IoC container
    object handlerInstance = this.ResolveHandler<T>(handlerType);

    // i can guarantee the instance implements IDomainEventSubscriber<T> where T
    // is the same type as eventToPublish

    Type typeInfo = typeof(IDomainEventSubscriber<T>);
    MethodInfo methodInfo = typeInfo.GetMethod("HandleEvent");

   // this line throws an error :(
    methodInfo.Invoke(handlerInstance, new object[] { eventToPublish });
}
4

1 回答 1

4

我认为你根本不需要反思。鉴于您知道实例 implements IDomainEventSubscriber<T>,为什么不直接将其转换为呢?

// You could make ResolveHandler just return IDomainEventSubscriber<T> of course
var handler = (IDomainEventSubscriber<T>) ResolveHandler<T>(handlerType);

handler.HandleEvent(eventToPublish);

但是您的代码实际上对我来说似乎可以正常工作,已将其提取到一个简短但完整的程序中(如下)。methodInfo你有一个类型参数的事实System.Object表明,尽管它应该T是. 所以也许问题在于你的方法是如何被调用的?System.ObjectTestEvent

using System;
using System.Reflection;

public class TestEvent{}

public interface IDomainEventSubscriber<T>
{
    void HandleEvent(T domainEvent);
}

class TestEventHandler : IDomainEventSubscriber<TestEvent>
{
    public void HandleEvent(TestEvent domainEvent)
    {
        Console.WriteLine("Done");
    }
}

class Test
{
    static void Main(string[] args)
    {
        Dispatch<TestEvent>(new TestEvent(), typeof(TestEventHandler));
    }

    static void Dispatch<T>(T eventToPublish, Type handlerType)
    {
        object handlerInstance = Activator.CreateInstance(handlerType);
        Type typeInfo = typeof(IDomainEventSubscriber<T>);
        MethodInfo methodInfo = typeInfo.GetMethod("HandleEvent");       
        methodInfo.Invoke(handlerInstance, new object[] { eventToPublish });
    }
}
于 2013-05-11T15:33:00.550 回答