我可以在 Prism 的 EventAggregator 上使用反射吗?
Can I use reflection on Prism's EventAggregator?
我正在尝试在 PRISM 框架中重构我的一些方法,但并没有真正奏效。
我需要通过 EventAggregator
发布消息,我已经编写了一个反射方法,它将查看包含 Type
的 List<Parameters>
并从这里发送消息。
但它从不发送任何消息。
事实证明safecast 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<object>
),它是相同的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);
如何将泛型类型传递给 void SomeFunction()
void SomeFunction<T>()
{
// ..............
var returnObj = genericMethod.Invoke(_eventAggregator, null) as PubSubEvent<T>;
returnObj?.Publish(data);
}
// call it like:
SomeFunction<DataObject>();
更新:
从 Type 调用泛型方法,可以这样完成:
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[] { });
傻我。这是反思——更多的反思!
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
,并从反射对象 returnObj
反射函数 Publish(...)
和 Invoke
,并使用 data
参数。
我正在尝试在 PRISM 框架中重构我的一些方法,但并没有真正奏效。
我需要通过 EventAggregator
发布消息,我已经编写了一个反射方法,它将查看包含 Type
的 List<Parameters>
并从这里发送消息。
但它从不发送任何消息。
事实证明safecast 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<object>
),它是相同的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);
如何将泛型类型传递给 void SomeFunction()
void SomeFunction<T>()
{
// ..............
var returnObj = genericMethod.Invoke(_eventAggregator, null) as PubSubEvent<T>;
returnObj?.Publish(data);
}
// call it like:
SomeFunction<DataObject>();
更新:
从 Type 调用泛型方法,可以这样完成:
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[] { });
傻我。这是反思——更多的反思!
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
,并从反射对象 returnObj
反射函数 Publish(...)
和 Invoke
,并使用 data
参数。