【问题标题】:Can I use reflection on Prism's EventAggregator?我可以在 Prism 的 EventAggregator 上使用反射吗?
【发布时间】:2015-10-21 14:02:47
【问题描述】:

我正在尝试在 PRISM 框架中重构我的一些方法,但并没有真正奏效。

我需要通过EventAggregator 发布消息,并且我编写了一个反射方法,它将查看包含Types 的List<Parameters> 并从这里发送消息。 但它从不发送任何消息。

原来安全广播as PubSubEvent<object>public class Input: PubSubEvent<Output> {}不一样,这意味着returnObj?.Publish(data);null,不会被调用。

public struct Parameters
{
    public string Topic;
    public Type Input;
    public Type Output;
}


private List<Parameters> _list;
...
void SomeFunction()
{
    _list.ForEach(m =>
    {
        var data = JsonConvert.DeserializeObject(dataString, m.Output);

        var eventAggType = _eventAggregator.GetType();
        var eventMethod = eventAggType.GetMethod("GetEvent");
        var genericMethod = eventMethod.MakeGenericMethod(m.Input);
        var returnObj = genericMethod.Invoke(_eventAggregator, null) as PubSubEvent<object>;
        returnObj?.Publish(data);

        // var datType = returnObj.GetType();
        // if (datType.BaseType.Name == typeof (PubSubEvent<object>).Name)
        // {
        //  var obj = Convert.ChangeType(returnObj, datType);
        //  ((PubSubEvent<object>) obj).Publish(data);
        // }
    }
}

我试图通过查看它实际输出的类型来修改代码(删除as PubSubEvent&lt;object&gt;),它是相同的BaseType。 但是转换为基本的PubSubEvent 并不是程序乐于看到的。

Exception thrown: 'System.InvalidCastException' in MyProject.ModuleA.dll

EXCEPTION: Unable to cast object of type 'MyProject.ModuleA.GlobalEvents.EventA' to type 'Microsoft.Practices.Prism.PubSubEvents.PubSubEvent`1[System.Object]'.

我如何Publish 使用正确的类型? 如果您知道自己在处理哪些类,它应该如下所示:

_eventAggregator.GetEvent<EventA>().Publish(data);

【问题讨论】:

    标签: c# reflection prism eventaggregator


    【解决方案1】:

    如何将泛型类型传递给void SomeFunction()

    void SomeFunction<T>()
    {
        // ..............
    
        var returnObj = genericMethod.Invoke(_eventAggregator, null) as PubSubEvent<T>;
        returnObj?.Publish(data);
    }
    
    
    // call it like:
    SomeFunction<DataObject>();
    

    更新:

    从一个类型调用一个泛型方法,可以这样完成:

    void SomeFunction<T>()
    {
        // ..............
    
        var returnObj = genericMethod.Invoke(_eventAggregator, null) as PubSubEvent<T>;
        returnObj?.Publish(data);
    }
    
    
    // call it like:
    
    // this is the type you want to pass.
    Type genericType = typeof(int);
    
    // get the MethodInfo
    var someFunctionMethodInfo = typeof(Program).GetMethod("SomeFunction", BindingFlags.Public);
    
    // create a generic from it
    var genericSomeFunctionMethodInfo = someFunctionMethodInfo.MakeGenericMethod(genericType);
    
    // invoke it.
    genericSomeFunctionMethodInfo.Invoke(null, new object[] { });
    

    【讨论】:

    • 是的,我应该详细说明。当我尝试调用SomeFunction() 时,我正在从List&lt;Parameters&gt; 传递一个存储的Type。所以我运行_list.foreach( m=&gt; ...,我只知道这个列表中的类型。也许List&lt;&gt; 可以重写为其他内容以使其适合?
    • 您应该将 foreach 带到函数之外。然后可以调用具有特定类型的方法。请参阅上面的更新。 (就像你上面用泛型做的把戏)
    • 是的,还不错——所以我可以在泛型方法之外做更多反射,或者我可以在函数内部再做两行反射(我找到了解决方案)。
    【解决方案2】:

    我傻了。这是反思 - 更多反思!

    void SomeFunction()
    {
        _list.ForEach(m =>
        {
            //Deserialize the data
            var data = JsonConvert.DeserializeObject(dataString, m.Output);
    
            //Obtain the object from the EventAggregator
            var eventAggType = _eventAggregator.GetType();
            var eventMethod = eventAggType.GetMethod("GetEvent");
            var genericMethod = eventMethod.MakeGenericMethod(m.Input);
            var returnObj = genericMethod.Invoke(_eventAggregator, null);
    
            //Publish the data
            var publishMethod = returnObj.GetType().GetMethod("Publish");
            publishMethod.Invoke(returnObj, new[] {data});
        });
    }
    

    因此,您采用反射 returnObj,并使用 data 参数从反射对象 returnObj 反射函数 Publish(...)Invoke

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-30
      • 2015-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多