Преобразование JObject в тип во время выполнения

Я пишу простой диспетчер событий, в котором мои события поступают как объекты с именем типа clr и объектом json, представляющим исходное событие (после того, как byte[] был обработан в jobject), которое было запущено. Я использую GetEventStore, если кто-то хочет знать подробности.

Я хочу использовать этот тип clr для двух вещей:

  1. найти классы, реализующие IHandles и
  2. вызов Consume (тип clr) для этого класса

Мне удалось заставить часть 1 работать нормально со следующим кодом:

     var processedEvent = ProcessRawEvent(@event);
     var t = Type.GetType(processedEvent.EventClrTypeName);

     var type = typeof(IHandlesEvent<>).MakeGenericType(t);

     var allHandlers = container.ResolveAll(type);


     foreach (var allHandler in allHandlers)
     {
         var method = allHandler.GetType().GetMethod("Consume", new[] { t });
         method.Invoke(allHandler, new[] { processedEvent.Data });
     }

ATM проблема в том, чтоprocessedEvent.Data является JObject - я знаю типprocessEvent.Data, потому что я не определил его выше.

Как я могу разобрать этот JObject в тип t, не делая никаких неприятных переключений на имя типа?


person Community    schedule 30.07.2014    source источник
comment
Пробовали ли вы DeserializeObject?   -  person cynic    schedule 30.07.2014
comment
Да, чувствую себя немного глупо сейчас :)   -  person    schedule 30.07.2014


Ответы (3)


Используйте 1_:

var data = processedEvent.Data.ToObject(t);

или если у вас есть известный тип, то:

MyObject data = processedEvent.Data.ToObject<MyObject>();
person Amir Popovich    schedule 30.07.2014
comment
.ToObject(Type...) доступен только после JSON.NET 4.5 или около того, если по какой-то причине вы застряли на более старом пакете - person drzaus; 24.02.2015
comment
JObject и ToObject появляются в одной и той же версии Json.net (версия: 7.0.0.0). newtonsoft.com/json/help/html/ newtonsoft.com/json/help/html/ - person Amir Popovich; 24.02.2015
comment
да, потому что версия 7 после версии 4.5, на что ссылается мой комментарий - это был добавлен 11/2012 версии 4.5.11. - person drzaus; 25.02.2015
comment
Это неправильно. Прежде всего, json.net не имеет ничего общего с версией .net framework. Вы утверждаете, что все, что было добавлено после 11/2012, будет работать только на 4.5.11? Во-вторых, я открыл фреймворк .net 3.5, получил пакет json.net от nuget и смог вызвать JObject.ToObject. - person Amir Popovich; 25.02.2015
comment
Я думаю, вы меня неправильно поняли — я говорю о версии 4.5 пакета Newtonsoft Json.NET., а не .NET framework. Ваш ответ совершенно прекрасен, я только упоминаю (довольно абсурдное) предостережение на случай, если кто-то еще попадет сюда в той же ситуации, в которой я нахожусь (ограничен более старым пакетом). - person drzaus; 25.02.2015
comment
Спасибо, @drzaus, это мой случай, я на JSON.NET 3.5.0.0 :( - person tsul; 05.04.2018

Это оказалось очень просто:

method.Invoke(allHandler, new[] { JsonConvert.DeserializeObject(processedEvent.Data.ToString(), t) });
person Community    schedule 30.07.2014

Если по какой-то причине вы застряли на более старом пакете Newtonsoft Json.NET (pre 4.5.11 около 2012 г.) и не имеют доступа к уже упомянутому JToken.ToObject(Type) можно повторно использовать что он делает внутри:

var someJObject = ...; // wherever it came from; actually a JToken
var type = typeof(MyExpectedType);

MyExpectedType myObject;
using (var jsonReader = new JTokenReader(someJObject))
    myObject = serializer.Deserialize(jsonReader, type);

Я упоминаю об этом только потому, что работал над проектом, в котором не мог просто обновить пакет Nuget для Json.NET до последней версии. Кроме того, это не имеет ничего общего с версией .NET framework.

person drzaus    schedule 25.02.2015