2015-10-21 2 views
0

Я пытаюсь реорганизовать некоторые из моих методов в инфраструктуре PRISM, и это не работает.Могу ли я использовать отражение в EventAggregator Prism?

мне нужно публиковать сообщения через EventAggregator, и я написал метод отражения, который будет смотреть через List<Parameters> содержащие Type с и отсюда отправлять сообщения. Но он никогда не отправляет никаких сообщений.

Оказывается 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 '. Итак, я запустил '_list.foreach (m => ...', где я знаю только тип из этого списка. Возможно, 'List <>' может быть переписан на что-то еще, чтобы сделать его подходящим? –

+0

Вы должны вывести метод foreach за пределы функции, тогда можно вызвать метод с определенным типом. См. мое обновление выше. _ (как трюк, который вы делали выше с помощью генериков) _ –

+0

Да, неплохо - так что я могу сделать больше отражения вне генетический метод, или я могу сделать еще две линии отражения внутри функции (я нашел решение). –

Смежные вопросы