Конвертировать JObject в тип во время выполнения
Я пишу простой диспетчер событий, в котором мои события появляются как объекты с именем типа clr и объектом json, представляющим исходное событие (после обработки байта [] в задании), которое было запущено. Я использую GetEventStore, если кто-то хочет знать специфику.
Я хочу взять этот тип clr, чтобы сделать 2 вещи:
- найти классы, которые реализуют IHandles и
- вызовите 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 проблема заключается в том, что processingEvent.Data является JObject - я знаю тип processingEvent.Data, потому что я определил его выше.
Как я могу разобрать этот объект JObject в тип t без каких-либо неприятных переключений на имя типа?
3 ответа
Использование ToObject
:
var data = processedEvent.Data.ToObject(t);
или если у вас есть известный тип, то:
MyObject data = processedEvent.Data.ToObject<MyObject>();
Это оказалось действительно легко:
method.Invoke(allHandler, new[] { JsonConvert.DeserializeObject(processedEvent.Data.ToString(), t) });
Если по какой-то причине вы застряли на более старом пакете Newtonsoft Json.NET ( до 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.