执行时
JsonConvert.DeserializeObject(value, type);
将为给定对象创建一个新对象
type
用于反序列化。我的要求是使用已创建的对象进行反序列化
CustomObject obj = new CustomObject(); //passing constructor args
JsonConvert.DeserializeObject(value, obj);
但此重载不可用。
那么,有没有什么解决方法可以让我使用已经创建的对象,而不是通过反序列化器创建新类型。?
我为什么要这样做?(详图)
我正在编写一个从JSON到c类的通用映射器。JSON的结构如下所示
{
"ActionType" : "LogEvent", //this is actually class name in a specific namespace
"Settings" : {
"FailureRetries" : 4,
"LogChannel" : 1234 // log channel id, implementation detail
}
}
我在配置映射器中执行的操作如下
public void IAction GetActionFromConfig(){
dynamic config = configManager.Load<dynamic>(); //loads JSON file.
string className = config.ActionType; //from config we will get file name.
Type type = Type.GetType(nameSpaceForConfig + "." + className);
string settingValue = JsonConvert.SerializeObject(config.Settings);
object actionObject = JsonConvert.DeserializeObject(settingValue, type);
return (IAction)actionObject; // return the IAction from config.
}
我的问题是
IAction
实现类在构造函数中可能有一些依赖项(例如
ILogger
)默认情况下,反序列化不会初始化构造函数参数。我知道我可以覆盖
JsonConverter
对于构造函数初始化,但在编写通用映射器时,我无法使用自定义
JsonConverter公司
.
我计划做的是首先创建一个映射
Type
(c)#
类型
类)转换为依赖项解决的特定实现。
其次,我将获得给定操作类型的构造函数(config中给定的类型为
ActionType
参数)
Type type = Type.GetType(nameSpaceForConfig + "." + className);
var ctors = typeof(type).GetConstructors();
var ctor = ctors[0];
List<Type> constructorArguments = new List<Type();
foreach (var param in ctor.GetParameters())
{
constructorArguments.Add(param.ParameterType);
}
然后,我将查询在步骤1中创建的词典。获取构造函数的参数。
最后,我将使用
Activator.CreateInstance()
(传递上一步中获得的构造函数依赖项)。
然后使用此对象进行反序列化,以通过配置文件初始化公共属性。
所以,这就是为什么我需要在
object
不在
类型
.
注:
前提条件是每个操作都应该有一个包含所有依赖项的构造函数。
旁白:
configManager.Load<T>
实施
public T Load<T>() where T : class, new() => Load(typeof(T)) as T;
public object Load(Type type)
{
if (!File.Exists(_configurationFilePath))
return Activator.CreateInstance(type);
var jsonFile = File.ReadAllText(_configurationFilePath);
return JsonConvert.DeserializeObject(jsonFile, type, JsonSerializerSettings);
}