2015-08-10 11 views
6

Nicht ganz gleich wie diese zu bekommen:Gibt es eine Möglichkeit Dependency Injection mit einem JsonConverter abgeleiteten benutzerdefinierten Konverter

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

Wo die Antwort ist, dass Ihre Datenklasse, die Sie einen Dienst nicht benötigen deserialisiert sollten sowieso. Gibt es eine Möglichkeit, die Abhängigkeit inject mit einer von JsonConverter abgeleiteten Klasse zu verwenden? Zum Beispiel, wenn Sie dies hatte:

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

Und:

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(); 
     //... 
    } 
} 

Gibt es trotzdem in einzuhaken, wie JSON.Net instanziiert MyCustomConverter, um es zu lassen Ninject tun es Sache ist?

BEARBEITEN Dies ist kein Service in Foo injizieren wie die vorgeschlagene Betrogene. Dies wird nur in MyCustomConverter injiziert, so dass es Foo deserialize kann.

+2

@StriplingWarrior: Das Duplikat ist nicht ganz dasselbe. Ich versuche nicht, das Objekt, das ich deserialisiere, in * zu injizieren. Das Objekt, das ich deserialisiere, benötigt keine Dienste, nur der JSON-Konverter benötigt die Abhängigkeitsinjektion. –

+1

Könnten Sie Ihrem Typ 'MyCustomConverter' ein statisches Ereignis (thread static?) Hinzufügen, mit dem ein' IMyService' in benutzerdefinierten Ereignisargumenten zurückgegeben werden kann. Unbeholfen, aber [machbar] (http://stackoverflow.com/questions/1210026/return-a-value-from-an-event-isti-there-a-good-practice-for-this). Vielleicht auch hier: http://blog.ploeh.dk/2013/09/08/dian-and-events-third-party-connect/ – dbc

+0

@dbc: Eine interessante Idee, darüber müsste ich nachdenken ein. –

Antwort

1

Es ist ein bisschen ein Hack, aber es ist möglich, etwas ähnliches zu tun, indem Sie den ContractResolver in den JsonSerializerSettings setzen. In diesem Fall mit Autofac:

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

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

und dann in den Konverter:

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

Sie sind also nicht wirklich den Dienst in den Konverter eingespritzt wird, aber zumindest können Sie darauf zugreifen, ohne eine konkrete Abhängigkeit. Außerdem verwenden Sie nicht denselben Autofac-Container wie Ihre App, sondern erstellen einen neuen. Nicht ideal, aber es ist etwas :)