2015-10-21 54 views
0

我想重構我在PRISM框架中的一些方法,但它並沒有真正解決問題。我可以在Prism的EventAggregator上使用反射嗎?

我需要通過EventAggregator發佈消息,並且我寫了一個反射方法,它將查看包含TypeList<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); 

回答

0

愚蠢的我。這是反思 - 多思考!

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,體現功能Publish(...)Invoke它從你反映的對象,returnObj,與data參數。

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[] { }); 
+0

是的,我要闡述。 當我嘗試調用'SomeFunction()'我傳遞一個存儲'Type'從列表''。 因此,我運行'_list.foreach(m => ...',我只知道這個列表中的類型。 也許'List <>'可以重寫爲其他內容以使它適合? –

+0

您應該。帶來的foreach功能之外,那麼就可以調用與特定類型的方法見我上面的更新_(如招你使用泛型沒有以上)_ –

+0

是的,不壞 - 所以我可以在外面做更多的思考或者我可以在函數內部做另外兩行反射(我找到了解決方案)。 –

相關問題