8

Not quite the same as this:

How do I Inject Dependencies with Ninject, where instances are deserialised from json

Where the answer is that your data class that you deserialized shouldn't need a service anyway. Is there a way to use dependency inject with a class derived from JsonConverter? For example, if you had this:

[JsonConverter(typeof(MyCustomConverter))]
public class Foo
{
    public string SomeProp { get; set; }
}

And:

public class MyCustomConverter : JsonConverter
{
    private readonly IMyService myService;

    public MyCustomConverter(IMyService _myService)
    {
        myService = _myService;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var bar = myService.SomeFunctionThatMightEffectDeserialization();
        //...
    }
}

Is there anyway to hook into how JSON.Net instantiates MyCustomConverter to get it to let Ninject do it's thing?

EDIT This is NOT injecting a service into Foo like the suggested dupe. This is injecting only into MyCustomConverter so that it can then deserialize Foo.

11
  • 4
    @StriplingWarrior: The duplicate isn't quite the same. I'm not looking to inject into the object I'm deserializing. The object I'm deserializing doesn't need any services, only the json converter needs dependency injection. Commented Aug 10, 2015 at 19:46
  • 1
    Could you add some static (thread static?) event to your MyCustomConverter type that allows an IMyService to be returned in custom event args. Awkward, but doable. Also, maybe see here: blog.ploeh.dk/2013/09/08/di-and-events-third-party-connect Commented Aug 10, 2015 at 20:00
  • @dbc: An interesting idea, I'd have to think about that one. Commented Aug 10, 2015 at 20:05
  • 1
    @davethieben quite obviously newtonsoft.json Commented Aug 10, 2015 at 20:14
  • 1
    @MattBurland JsonTypeReflector is the class responsible for the instantication, if you'd like to have a look. Commented Aug 10, 2015 at 20:25

1 Answer 1

1

It's a bit of a hack, but it's possible to do something similar by setting the ContractResolver in the JsonSerializerSettings. In this case, using Autofac:

var builder = new ContainerBuilder();
builder.RegisterInstance(myService);
var container = builder.Build();

var settings = new JsonSerializerSettings
{
    ContractResolver = new AutofacContractResolver(container),
};

and then in the converter:

var jsonContract = serializer.ContractResolver.ResolveContract(typeof(IMyService));
var service = (IMyService)jsonContract.DefaultCreator();

So you're not really injecting the service into the converter, but at least you can access it without a concrete dependency. Also you're not using the same Autofac container as your app but creating a new one. Not ideal, but it's something :)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.