Json.NET如何反序列化期间执行依赖注入? [英] How can Json.NET perform dependency injection during deserialization?

查看:129
本文介绍了Json.NET如何反序列化期间执行依赖注入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



当我使用依赖注入通过它的依赖有一个类没有默认构造函数,即能 Newtonsoft.Json 创建这样一个?反对



例如:



<预类=郎-CS prettyprint-覆盖> 公共类SomeFoo
{
私人只读IFooDependency _dependency;

公共SomeFoo(IFooDependency依赖){
如果(依赖== NULL)
抛出新的ArgumentNullException(依赖);

_dependency =依赖;
}

公共字符串数据{搞定;组; }
公众诠释MOREDATA {搞定;组; }

公共无效DoFoo(){
数据= _dependency.GetFooData();
MOREDATA = _dependency.GetMoreFooDate();
}
}



在系列化,我只关心存储数据和MOREDATA的(对象和类型,但是让我们不要在目前复杂的事情)。现在,反序列化,我可以调用类似



<预类=郎-CS prettyprint-覆盖> VAR OBJ = JsonConvert.DeserializeObject< SomeFoo> (jsonText);



我怎样才能让JsonConvert知道我的DI容器吗



(注:一个变通将永远在我的类默认构造,并调用服务定位在那里得到我需要的任何依赖关系,我只是在寻找一些。更清洁的解决方案,而poluting我的班,这样的构造函数)。


解决方案


我同意分离张贴由史蒂芬的关注,得到的答复马克·塞曼已此处发布但是,如果你还想走这条路,这里是一个解决方案,它可以帮助:



继承 CustomCreationConverter< ; T>

 内部类NinjectCustomConverter< T> :CustomCreationConverter< T>其中T:类
{
私人只读IResolutionRoot _serviceLocator;

公共NinjectCustomConverter(IResolutionRoot的ServiceLocator)
{
_serviceLocator =服务定位;
}

公众覆盖牛逼创建(类型的objectType)
{
返回_serviceLocator.Get(的objectType)为T;
}
}



然后确保您通过DI检索该转换器实例容器为好。下面的代码将反序列化在对象上执行DI:

  VAR ninjectConverter = kernel.Get< NinjectCustomConverter< SerializedObject>>(); 
VAR设置=新JsonSerializerSettings();
settings.Converters.Add(ninjectConverter);

无功实例= JsonConvert.DeserializeObject< SerializedObject>(JSON,设置);

这里是一个完整的工作示例


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

Here is a complete working example.

这篇关于Json.NET如何反序列化期间执行依赖注入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆