using System.Collections.Generic;
using Newtonsoft.Json.Linq;
public static void Main()
IQuoteRepository repo = new QuoteRepository();
IRequest req = new Request
QuoteDate = DateTime.Parse("2016-05-11T23:00:00-05:00"),
Description = "SPDR S&P 500",
QuoteTimeStamp = DateTime.Parse("2016-05-11T15:00:01-05:00"),
repo.AddQuote(req, quote);
QuoteDate = DateTime.Parse("2016-05-11T23:00:00-05:00"),
Description = "Alphabet Inc.",
QuoteTimeStamp = DateTime.Parse("2016-05-11T15:00:00-05:00"),
repo.AddQuote(req, quote);
JsonSerializerSettings settings = new JsonSerializerSettings
Converters = new List<JsonConverter>
new CustomDictionaryConverter<IRequest, IQuoteTimeSeries>("Request", "Data"),
new CustomDictionaryConverter<DateTime, IQuote>("TimeStamp", "Quote")
Formatting = Formatting.Indented
string json = JsonConvert.SerializeObject(repo, settings);
public class CustomDictionaryConverter<K, V> : JsonConverter
private string KeyPropertyName { get; set; }
private string ValuePropertyName { get; set; }
public CustomDictionaryConverter(string keyPropertyName, string valuePropertyName)
KeyPropertyName = keyPropertyName;
ValuePropertyName = valuePropertyName;
public override bool CanConvert(Type objectType)
return typeof(IDictionary<K, V>).IsAssignableFrom(objectType);
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
IDictionary<K, V> dict = (IDictionary<K, V>)value;
JArray array = new JArray();
foreach (var kvp in dict)
JObject obj = new JObject();
obj.Add(KeyPropertyName, JToken.FromObject(kvp.Key, serializer));
obj.Add(ValuePropertyName, JToken.FromObject(kvp.Value, serializer));
public override bool CanRead
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
throw new NotImplementedException();
public class QuoteRepository : Dictionary<IRequest, IQuoteTimeSeries>, IQuoteRepository
public QuoteRepository() { }
public void AddRequest(IRequest request)
if (!this.ContainsKey(request))
IQuoteTimeSeries tSeries = new QuoteTimeSeries(request);
this.Add(request, tSeries);
public void AddQuote(IRequest request, IQuote quote)
this[request].AddQuote(quote);
public class QuoteTimeSeries : SortedDictionary<DateTime, IQuote>, IQuoteTimeSeries
public QuoteTimeSeries(IRequest request)
public IRequest Request { get; private set; }
public void AddQuote(IQuote quote)
this[quote.QuoteTimeStamp] = quote;
public interface IQuoteRepository
void AddRequest(IRequest request);
void AddQuote(IRequest request, IQuote quote);
public interface IQuoteTimeSeries
void AddQuote(IQuote quote);
public interface IRequest
DateTime QuoteDate { get; set; }
string QuoteType { get; set; }
string Symbol { get; set; }
Boolean UseCache { get; set; }
public class Request : IRequest
public DateTime QuoteDate { get; set; }
public string QuoteType { get; set; }
public string Symbol { get; set; }
public Boolean UseCache { get; set; }
string Description { get; set; }
decimal High { get; set; }
decimal Low { get; set; }
decimal Change { get; set; }
decimal ChangePer { get; set; }
decimal Price { get; set; }
DateTime QuoteTimeStamp { get; set; }
string Symbol { get; set; }
public class Quote : IQuote
public string Description { get; set; }
public decimal High { get; set; }
public decimal Low { get; set; }
public decimal Change { get; set; }
public decimal ChangePer { get; set; }
public decimal Price { get; set; }
public DateTime QuoteTimeStamp { get; set; }
public string Symbol { get; set; }