Sto provando a creare un file di configurazione usando Json che manterrà la configurazione per vari tipi di oggetti.Deserializzare con Json.Net, deserializzare l'oggetto secondario in stringa/simile che contiene il json?
Considerate questo file:
{
"cameras": [
{
"type": "Some.Namespace.CameraClass",
"assembly": "Some.Assembly",
"configuration": {
"ip": "127.0.0.1",
"port": 8080
}
}
]
}
In runtime Userò il "tipo" due e "assemblaggio" proprietà per costruire un oggetto che supporta un'interfaccia specifica, e quindi vorrei caricare la configurazione in cui oggetto.
Tuttavia, al momento della compilazione non conosco il tipo a cui la "configurazione" verrebbe associata. Mi piacerebbe conservarlo come una "proprietà" json e inserirlo nell'oggetto della telecamera, e quindi lasciare che quell'oggetto deserializzi il json nel tipo giusto.
Come tale mi piacerebbe semplicemente "trasportare" la parte del file di configurazione che contiene la configurazione per un particolare tipo di telecamera con me nell'oggetto stesso, e lasciare che si occupi di esso, trattandolo come una scatola nera mentre porto così. La struttura di quella parte dovrebbe essere preservata dal momento che mi piacerebbe la massima fedeltà durante la creazione dei tipi di configurazione per ogni implementazione della telecamera, aggiungendo anche i sottooggetti se necessario.
Per questa particolare telecamera configurerei un indirizzo IP e una porta, per alcune altre fotocamere avrei bisogno di dati di autorizzazione e per qualche altra fotocamera qualcosa di completamente diverso.
Mi piacerebbe che la proprietà mantenga questa configurazione per ottenere direttamente Json, sempre come una stringa.
È possibile?
Ecco un esempio di LINQPad che ha alcuni pezzi commentata:
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();
}
}
I due commentate bit, vale a dire la proprietà nella classe Camera
, e la chiamata al metodo Configure
, è quello che mi piacerebbe come lavorare
C'è qualcosa che possa taggare quella proprietà con, o qualche altro tipo che posso scegliere per quella proprietà, che farebbe funzionare questo?
so di poter rendere la struttura dinamica, che roba un JObject
in esso, ma poi ognuno Configure
metodo per ogni implementazione fotocamera sarebbe avere a che fare con un JObject
e non un tipo noto non dinamica.
In che modo avresti una digitazione statica con il tuo attuale approccio? Non hai alcuna proprietà di 'ip' e' port', o comunque di una classe che rappresenta comunque la configurazione. Potresti * potenzialmente provare a creare il tipo di proprietà 'JObject', ma di nuovo non avresti intellisense. Non sono sicuro di come ti aspetti di ottenere Intellisense per questo ... –
All'interno del tipo specifico che sto caricando, prenderei il Json della configurazione e lo deserializzerò in un oggetto di configurazione noto a priori. In altre parole, il codice esterno che carica il file di configurazione considererebbe questa una scatola nera, ma l'implementazione effettiva della fotocamera sarebbe in grado di deserializzare questo a un tipo noto. –
Ma 'Camera.Configuration' non sarebbe di tipo concreto in fase di compilazione, quindi come ti aspetteresti che Intellisense funzioni? Se digito 'camera.Configurazione 'quali proprietà ti aspetteresti di vedere? Come ho detto, è possibile che JObject ti desse quello che vuoi, ma non l'ho provato. –