How can Json.NET perform dependency injection during deserialization?

前端 未结 3 2020
悲哀的现实
悲哀的现实 2021-01-07 18:53

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?

相关标签:
3条回答
  • 2021-01-07 19:10

    If your objective is to use the injected dependency to modify the data, then you can create a custom Converter.

    With this, you should be able to inject your dependency. Similar to the code below:

     var settings = new JsonSerializerSettings
                {
                    Converters = { new FooConverter<T>(injectedDependency) }
                };
     return JsonConvert.DeserializeObject<Dto>(json, settings);
    

    There're many samples of how to create a custom Converters, so you can refer to them.

    0 讨论(0)
  • 2021-01-07 19:19

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

    Here is a complete working example.

    0 讨论(0)
  • 2021-01-07 19:20

    You shouldn't let JsonConvert know anything about your DI container. The problems you're experiencing are caused by a flaw in the design of your application. The flaw here is that you mix data and behavior.

    If you separate the data from the behavior your problem (and many other problems) will simply go away. You can do this by creating two classes: one for the data, and one for the behavior:

    public class SomeFoo
    {
        public string Data { get; set; }
        public int MoreData { get; set; }
    }
    
    public class SomeFooHandler
    {
        private readonly IFooDependency _dependency;
    
        public SomeFooHandler(IFooDependency dependency) {
            _dependency = dependency;
        }
    
        public void Handle(SomeFoo foo) {
            foo.Data = _dependency.GetFooData();
            foo.MoreData = _dependency.GetMoreFooDate();
        }
    }
    

    Since now data and behavior are separated, SomeFoo can be serialized without any problem and SomeFooHandler can simply be injected. SomeFoo has becomes a Parameter Object.

    0 讨论(0)
提交回复
热议问题