Json.NET如何在反序列化期间执行dependency injection?

当我有一个没有默认构造函数的类,即使用dependency injection来传递其依赖项时, Newtonsoft.Json可以创建这样的对象吗?

例如:

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

在序列化过程中,我只关心存储Data和MoreData(以及对象的类型,但暂时不要复杂化)。 现在,为了反序列化,我可以调用类似的东西

 var obj = JsonConvert.DeserializeObject(jsonText); 

我怎样才能让JsonConvert了解我的DI容器?

(注意:解决方法是在我的类中始终使用默认构造函数,并在那里调用Service Locator以获得我需要的任何依赖项。我只是在寻找一些更简洁的解决方案,而不用使用这样的构造函数来规划我的类)。

我同意Steven发布的关注点分离,以及Mark Seemann在此发布的答案。 但是,如果你仍然想这样 ,这里有一个可能有用的解决方案:

inheritanceCustomCreationConverter

 internal class NinjectCustomConverter : CustomCreationConverter 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; } } 

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

 var ninjectConverter = kernel.Get>(); var settings = new JsonSerializerSettings(); settings.Converters.Add(ninjectConverter); var instance = JsonConvert.DeserializeObject(json, settings); 

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

你不应该让JsonConvert了解你的DI容器。 您遇到的问题是由应用程序设计中的缺陷引起的。 这里的缺陷是你混合数据和行为

如果您将数据与行为分开,您的问题(以及许多其他问题)将会消失。 您可以通过创建两个类来完成此操作:一个用于数据,另一个用于行为:

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

由于现在数据和行为是分开的, SomeFoo可以没有任何问题地序列化, SomeFooHandler可以简单地注入SomeFooHandlerSomeFoo已成为参数对象 。