Json.NET如何反序列化期间执行依赖注入? [英] How can Json.NET perform dependency injection during deserialization?
问题描述
当我使用依赖注入通过它的依赖有一个类没有默认构造函数,即能 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屋!