12

I am writing a simple event dispatcher where my events come in as objects with the clr type name and the json object representing the original event (after the byte[] has been processed into the jobject) that was fired. I'm using GetEventStore if anyone wants to know the specifics.

I want to take that clr type to do 2 things:

  1. find the classes that implements IHandles and
  2. call Consume(clr type) on that class

I have managed to get part 1 working fine with the following code:

     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 the issue is that processedEvent.Data is a JObject - I know the type of processedEvent.Data because I have t defined above it.

How can I parse that JObject into type t without doing any nasty switching on the type name?

mat-mcloughlin
  • 6,492
  • 12
  • 45
  • 62
  • 1
    Have you tried [`DeserializeObject`](http://james.newtonking.com/json/help/index.html?topic=html/Overload_Newtonsoft_Json_JsonConvert_DeserializeObject.htm)? – cynic Jul 30 '14 at 07:40
  • Yeah - feel a bit stupid now :) –  Jul 30 '14 at 08:42

3 Answers3

17

Use ToObject:

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

or if you have a known type then:

MyObject data = processedEvent.Data.ToObject<MyObject>();
Amir Popovich
  • 29,350
  • 9
  • 53
  • 99
  • 1
    `.ToObject(Type...)` is only available after JSON.NET 4.5 or so, if for some reason you're stuck on an older package – drzaus Feb 23 '15 at 22:07
  • `JObject` and the `ToObject` both appear in the same `Json.net` version (Version: 7.0.0.0). http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_JObject.htm http://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_Linq_JToken_ToObject.htm – Amir Popovich Feb 24 '15 at 06:14
  • 1
    yes, because version 7 is after v4.5, which is what my comment refers to -- it [was added 11/2012](https://github.com/JamesNK/Newtonsoft.Json/commit/a8249e38df8c3f55cf3f22585222f245741e05d5#diff-8e0fcadcdad86fae606e713cf8279c59L1174) which is version 4.5.11 – drzaus Feb 24 '15 at 21:57
  • Thats incorrect. First of all json.net has nothing to do with the .net framework version. Do you claim that anything that was added after 11/2012 will run only on 4.5.11? Secondly, I've opened a .net 3.5 framework and got the json.net package from nuget and was able to call JObject.ToObject. – Amir Popovich Feb 25 '15 at 04:59
  • 1
    I think you misunderstood me -- I'm talking about version 4.5 of the [Newtonsoft Json.NET package](https://www.nuget.org/packages/Newtonsoft.Json/), not the .NET framework. Your answer is perfectly fine, I'm only mentioning the (fairly absurd) caveat in case anyone else gets here in the same situation I'm in (constrained to an older package). – drzaus Feb 25 '15 at 14:26
  • Thanks, @drzaus, that's my case, I'm on JSON.NET 3.5.0.0 :( – tsul Apr 05 '18 at 15:10
0

This turned out to be really easy:

method.Invoke(allHandler, new[] { JsonConvert.DeserializeObject(processedEvent.Data.ToString(), t) });
0

If, for some reason you're stuck on an older package of Newtonsoft Json.NET (pre 4.5.11 circa 2012) and don't have access to the already mentioned JToken.ToObject(Type), you can reuse what it does internally:

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);

I mention this only because I've worked on a project that I couldn't just update the Nuget package for Json.NET to the latest version. Also, this has nothing to do with the .NET framework version.

Community
  • 1
  • 1
drzaus
  • 24,171
  • 16
  • 142
  • 201