Reputation: 3483
I'd like to create a very general Model-Layer, which can also be passed arround as JSON. One Model should show a LED-Panel of a RaspberryPi2. Since I'd like to model the Class to be as near as possible to the reality, I force a List to always have 8 * 8 Leds. The Class is looking like this:
public class VisualLedPanel
{
private readonly Lazy<List<VisualLed>> _lazyVisualLeds = new Lazy<List<VisualLed>>(CreateVisualLeds);
public VisualLed this[int x, int y]
{
get
{
var result = VisualLeds.FirstOrDefault(f => f.X == x && f.Y == y);
return result;
}
}
public IEnumerable<VisualLed> VisualLeds
{
get
{
return _lazyVisualLeds.Value;
}
set
{
var tt = value;
}
}
private static List<VisualLed> CreateVisualLeds()
{
var result = new List<VisualLed>();
for (var x = 0; x <= 7; x++)
{
for (var y = 0; y <= 7; y++)
{
result.Add(new VisualLed(x, y));
}
}
return result;
}
}
The problem arises with the Serialization: I'm using the NewtonSoft. Json.Net Serializer, and as far as I've seen, it first accesses the Getter, which causes the Logic to create the Leds, and then sets them afterwards. The only solution I could think of would either be a Custom-Deserializer or some sort of Constructor shennenigans. It also seems like the Deserializer doesn't use the Set-Property of the VisualLeds-Value, since my Debugger-Stop never was hitted.
Is there an easy possibility arround to have the best of both worlds? I'd like to have the Model as general as possible without the need of Custom-Deserializer.
Upvotes: 3
Views: 132
Reputation: 116991
The easiest way for you to do this without having to write your own custom JsonConverter
will be to serialize your collection of VisualLed
objects as a proxy array property, marking the original property as ignored:
public class VisualLedPanel
{
private readonly Lazy<List<VisualLed>> _lazyVisualLeds = new Lazy<List<VisualLed>>(CreateVisualLeds);
public VisualLed this[int x, int y]
{
get
{
var result = VisualLeds.FirstOrDefault(f => f.X == x && f.Y == y);
return result;
}
}
[JsonIgnore]
public IEnumerable<VisualLed> VisualLeds
{
get
{
return _lazyVisualLeds.Value;
}
}
[JsonProperty("VisualLeds")]
VisualLed [] SerializableVisualLeds
{
get
{
return VisualLeds.ToArray();
}
set
{
if (value == null || value.Length == 0)
{
if (_lazyVisualLeds.IsValueCreated)
_lazyVisualLeds.Value.Clear();
}
else
{
_lazyVisualLeds.Value.Clear();
_lazyVisualLeds.Value.AddRange(value);
}
}
}
private static List<VisualLed> CreateVisualLeds()
{
var result = new List<VisualLed>();
for (var x = 0; x <= 7; x++)
{
for (var y = 0; y <= 7; y++)
{
result.Add(new VisualLed(x, y));
}
}
return result;
}
}
Prototype fiddle
For a further discussion, see Why are all the collections in my POCO are null when deserializing some valid json with the .NET Newtonsoft.Json component. Using ObjectCreationHandling.Replace
would not be appropriate in this case since you want your Lazy<List<VisualLed>> _lazyVisualLeds
to be read-only.
Upvotes: 2