2015-08-10 21 views
6

Non proprio la stessa cosa come questa:C'è un modo per ottenere l'iniezione di dipendenza con un convertitore personalizzato JsonConverter derivato

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

Se la risposta è che la classe di dati che deserializzata non dovrebbe avere bisogno di un servizio Comunque. C'è un modo per usare la dipendenza inject con una classe derivata da JsonConverter? Ad esempio, se si ha questo:

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

E:

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

Esiste un modo per collegare in modo JSON.Net crea un'istanza MyCustomConverter per farlo lasciare Ninject fare è cosa?

EDIT Questo NON inietta un servizio in Foo come il duplicato suggerito. Si sta iniettando solo in MyCustomConverter in modo da poter deserializzare Foo.

+2

@StriplingWarrior: Il duplicato non è esattamente la stessa cosa. Non sto cercando di iniettare * nell'oggetto che sto deserializzando. L'oggetto che sto deserializzando non ha bisogno di alcun servizio, solo il convertitore JSON ha bisogno dell'iniezione di dipendenza. –

+1

Potresti aggiungere qualche evento statico (thread statico?) Al tuo tipo 'MyCustomConverter' che permetta a un' IMyService' di essere restituito in argomenti di evento personalizzati. Imbarazzante, ma [fattibile] (http://stackoverflow.com/questions/1210026/return-a-value-from-an-event-is-there-a-good-practice-for-this). Inoltre, forse vedi qui: http://blog.ploeh.dk/2013/09/08/di-and-events-third-party-connect/ – dbc

+0

@dbc: un'idea interessante, dovrei pensarci uno. –

risposta

1

È un po 'un trucco, ma è possibile fare qualcosa di simile impostando ContractResolver in JsonSerializerSettings. In questo caso, utilizzando Autofac:

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

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

e poi nel convertitore:

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

Quindi non sei veramente iniettando il servizio nel convertitore, ma almeno si può accedere senza una concreta dipendenza. Inoltre, non stai utilizzando lo stesso contenitore Autofac della tua app ma ne stai creando uno nuovo. Non ideale, ma è qualcosa :)