我正在尝试使用 Json 创建一个配置文件,该文件将保存各种类型对象的配置。
考虑这个文件:
{
"cameras": [
{
"type": "Some.Namespace.CameraClass",
"assembly": "Some.Assembly",
"configuration": {
"ip": "127.0.0.1",
"port": 8080
}
}
]
}
在运行时,我将使用两个“类型”和“程序集”属性来构造一个支持特定接口的对象,然后我想将配置加载到该对象中。
但是,在编译时我不知道“配置”将映射到的类型。我想将其保留为 json“属性”并将其输入到相机对象中,然后让该对象将 json 反序列化为正确的类型。
因此,我想将包含特定相机类型配置的配置文件部分“携带”到对象本身中,并让它处理它,当我像这样携带它时,将其视为黑匣子。应保留该部分的结构,因为我希望在为每个相机实现创建配置类型时具有完全保真度,甚至在必要时添加子对象。
对于这个特定的摄像机,我将配置一个 IP 地址和端口,对于其他一些摄像机,我需要授权数据,而对于其他一些摄像机,我需要完全不同的数据。
我希望保存此配置的属性能够直接获取 Json,仍然是字符串。
这可能吗?
这里有一个LINQPad http://linqpad.net注释掉一些位的示例:
void Main()
{
const string configurationFile = @"[
{
""type"": ""UserQuery+Camera1"",
""configuration"": { ""id"": 10 }
},
{
""type"": ""UserQuery+Camera2"",
""configuration"": { ""name"": ""The second camera"" }
}
]";
var cameras = JsonConvert.DeserializeObject<Camera[]>(configurationFile);
foreach (var camera in cameras)
{
var type = Type.GetType(camera.Type);
var instance = Activator.CreateInstance(type, new object[0]) as ICamera;
// instance.Configure(camera.Configuration);
}
}
public class Camera
{
public string Type { get; set; }
public JObject Configuration { get; set; }
}
public interface ICamera
{
void Configure(string json);
}
public class Camera1 : ICamera
{
private class Configuration
{
public int Id { get; set; }
}
public void Configure(string json)
{
JsonConvert.DeserializeObject<Configuration>(json).Dump();
}
}
public class Camera2 : ICamera
{
private class Configuration
{
public string Name { get; set; }
}
public void Configure(string json)
{
JsonConvert.DeserializeObject<Configuration>(json).Dump();
}
}
这两个注释掉的位,即属性中Camera
类,并调用Configure
方法,就是我想要的工作。
有什么我可以标记该属性的东西,或者我可以为该属性选择的其他类型,这将使这项工作有效?
我知道我可以使财产充满活力,这将填充JObject
进入其中,但随后每个Configure
每个相机实现的方法都必须处理一个JObject
而不是已知的非动态类型。