When I have a class with no default constructor, i.e. using dependency injection to pass its dependencies, can Newtonsoft.Json
create such an object?
For example:
public class SomeFoo
{
private readonly IFooDependency _dependency;
public SomeFoo(IFooDependency dependency){
if(dependency == null)
throw new ArgumentNullException("dependency");
_dependency = dependency;
}
public string Data { get; set; }
public int MoreData { get; set; }
public void DoFoo(){
Data = _dependency.GetFooData();
MoreData = _dependency.GetMoreFooDate();
}
}
During serialization, I only care of storing Data and MoreData (and the type of the object, but let's don't complicate things for the moment). Now, to deserialize, can I call something like
var obj = JsonConvert.DeserializeObject<SomeFoo>(jsonText);
How can I let JsonConvert know about my DI container?
(Note: A work-around would be to always have default constructors in my classes, and call Service Locator in there to get any dependencies I need. I'm just looking for some more clean solution without poluting my classes with such constructors).
I agree with the separation of concerns posted by Steven, and the answer Mark Seemann has posted here. However, if you still want to go this way, here is a solution that may help:
Inherit a CustomCreationConverter<T>
:
internal class NinjectCustomConverter<T> : CustomCreationConverter<T> where T : class
{
private readonly IResolutionRoot _serviceLocator;
public NinjectCustomConverter(IResolutionRoot serviceLocator)
{
_serviceLocator = serviceLocator;
}
public override T Create(Type objectType)
{
return _serviceLocator.Get(objectType) as T;
}
}
Then make sure you retrieve this converter instance via your DI container as well. The code below will deserialize and perform DI on your object:
var ninjectConverter = kernel.Get<NinjectCustomConverter<SerializedObject>>();
var settings = new JsonSerializerSettings();
settings.Converters.Add(ninjectConverter);
var instance = JsonConvert.DeserializeObject<SerializedObject>(json, settings);