diff --git a/Directory.Packages.props b/Directory.Packages.props
index e51e66d..ee124af 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -4,7 +4,6 @@
-
@@ -12,6 +11,7 @@
+
diff --git a/src/FX.Core/FX.Core.fsproj b/src/FX.Core/FX.Core.fsproj
index b1da1f4..65d63ec 100644
--- a/src/FX.Core/FX.Core.fsproj
+++ b/src/FX.Core/FX.Core.fsproj
@@ -13,6 +13,6 @@
-
+
diff --git a/src/FX.Core/RedisStorageLayer.fs b/src/FX.Core/RedisStorageLayer.fs
index bedd39e..07a9070 100644
--- a/src/FX.Core/RedisStorageLayer.fs
+++ b/src/FX.Core/RedisStorageLayer.fs
@@ -5,9 +5,42 @@ open System
open FsharpExchangeDotNetStandard
-open Newtonsoft.Json
+open System.Text.Json
+open System.Text.Json.Serialization
open StackExchange.Redis
+[]
+module Serialization =
+ // TODO: use FSharp.SystemTextJson for Discriminated Union support,
+ // in that case custom type converters are no longer needed
+ type SideTypeConverter() =
+ inherit JsonConverter()
+
+ override this.Read(reader, _typeToConvert, _options) =
+ reader.GetString() |> Side.Parse
+
+ override this.Write(writer, value, _options ) =
+ writer.WriteStringValue(value.ToString())
+
+ type CurrencyTypeConverter() =
+ inherit JsonConverter()
+
+ override this.Read(reader, _typeToConvert, _options) =
+ match reader.GetString() with
+ | "BTC" -> BTC
+ | "USD" -> USD
+ | unknownCurrency -> failwithf "Unknown currency: %s" unknownCurrency
+
+ override this.Write(writer, value, _options ) =
+ writer.WriteStringValue(value.ToString())
+
+ let serializationOptions =
+ let options = JsonSerializerOptions()
+ options.Converters.Add(SideTypeConverter())
+ options.Converters.Add(CurrencyTypeConverter())
+ options
+
+
type OrderQuery =
{
OrderId: string;
@@ -26,9 +59,9 @@ type Query =
type OrderBookSide(market: Market, side: Side) =
let tipQuery = { Market = market; Tip = true; Side = side }
- let tipQueryStr = JsonConvert.SerializeObject tipQuery
+ let tipQueryStr = JsonSerializer.Serialize(tipQuery, serializationOptions)
let tailQuery = { Market = market; Tip = false; Side = side }
- let tailQueryStr = JsonConvert.SerializeObject tailQuery
+ let tailQueryStr = JsonSerializer.Serialize(tailQuery, serializationOptions)
member __.TipQuery = tipQueryStr
member __.TailQuery = tailQueryStr
@@ -53,7 +86,7 @@ module OrderRedisManager =
db.CreateTransaction()
let InsertOrder (limitOrder: LimitOrder): unit =
- let serializedOrder = JsonConvert.SerializeObject limitOrder
+ let serializedOrder = JsonSerializer.Serialize(limitOrder, serializationOptions)
let success = db.StringSet(RedisKey.op_Implicit (limitOrder.OrderInfo.Id.ToString()),
RedisValue.op_Implicit (serializedOrder))
if not success then
@@ -89,7 +122,7 @@ module OrderRedisManager =
let orderSerialized = db.StringGet (RedisKey.op_Implicit tipOrderGuid)
if not orderSerialized.HasValue then
failwithf "Something went wrong, order tip was %s but was not found" tipOrderGuid
- let tipOrder = JsonConvert.DeserializeObject (orderSerialized.ToString())
+ let tipOrder = JsonSerializer.Deserialize(orderSerialized.ToString(), serializationOptions)
tipOrder |> Some
let private GetOrderSerialized (guidStr: string): Option =
@@ -111,7 +144,7 @@ module OrderRedisManager =
match maybeOrderSerialized with
| None -> None
| Some orderSerialized ->
- let order = JsonConvert.DeserializeObject (orderSerialized.ToString())
+ let order = JsonSerializer.Deserialize(orderSerialized.ToString(), serializationOptions)
order |> Some
let GetOrderByGuid (guid: Guid): Option =
@@ -122,13 +155,13 @@ module OrderRedisManager =
if not tail.HasValue then
List.empty
else
- JsonConvert.DeserializeObject> (tail.ToString())
+ JsonSerializer.Deserialize>(tail.ToString(), serializationOptions)
let SetTail (transaction: StackExchange.Redis.ITransaction)
(limitOrderGuids: List)
(orderBookSide: OrderBookSide)
: unit =
- let serializedGuids = JsonConvert.SerializeObject limitOrderGuids
+ let serializedGuids = JsonSerializer.Serialize(limitOrderGuids, serializationOptions)
transaction.StringSetAsync(RedisKey.op_Implicit orderBookSide.TailQuery,
RedisValue.op_Implicit serializedGuids)
|> ignore
diff --git a/src/FX.Tests/FX.Tests.csproj b/src/FX.Tests/FX.Tests.csproj
index 7bef3f5..0a2ee99 100644
--- a/src/FX.Tests/FX.Tests.csproj
+++ b/src/FX.Tests/FX.Tests.csproj
@@ -9,8 +9,8 @@
-
+
diff --git a/src/FX.Tests/RedisIntegrationTests.cs b/src/FX.Tests/RedisIntegrationTests.cs
index 19697e6..a8df019 100644
--- a/src/FX.Tests/RedisIntegrationTests.cs
+++ b/src/FX.Tests/RedisIntegrationTests.cs
@@ -5,7 +5,7 @@
using FsharpExchangeDotNetStandard;
using FsharpExchangeDotNetStandard.Redis;
-using Newtonsoft.Json;
+using System.Text.Json;
using NUnit.Framework;
using StackExchange.Redis;
@@ -33,8 +33,8 @@ private Exchange CreateExchangeAndSendFirstLimitOrder
var tipQuery = new MarketQuery(market, limitOrder.OrderInfo.Side, true);
- //e.g. {"Market":{"BuyCurrency":{"Case":"BTC"},"SellCurrency":{"Case":"USD"}},"Side":{"Case":"Buy"},"Tip":true}"
- string tipQueryStr = JsonConvert.SerializeObject(tipQuery);
+ //e.g. {"Market":{"BuyCurrency":"BTC","SellCurrency":"USD"},"Side":"Bid","Tip":true}"
+ string tipQueryStr = JsonSerializer.Serialize(tipQuery, Serialization.serializationOptions);
using (var redis = ConnectionMultiplexer.Connect("localhost"))
{
@@ -76,7 +76,7 @@ private Exchange CreateExchangeAndSendFirstLimitOrder
"should have the order content(not null)");
var limitOrderSerialized =
- JsonConvert.SerializeObject(limitOrder);
+ JsonSerializer.Serialize(limitOrder, Serialization.serializationOptions);
Assert.That(order.ToString(),
Is.EqualTo(limitOrderSerialized),
"received order should have same content");
@@ -129,8 +129,8 @@ public void SendingSecondAndThirdLimitOrderMakesNonTipQueryWorkAfter()
var nonTipQuery = new MarketQuery(market, side, false);
- //e.g. {"Market":{"BuyCurrency":{"Case":"BTC"},"SellCurrency":{"Case":"USD"}},"Side":{"Case":"Buy"},"Tip":true}"
- string nontipQueryStr = JsonConvert.SerializeObject(nonTipQuery);
+ //e.g. {"Market":{"BuyCurrency":"BTC","SellCurrency":"USD"},"Side":"Bid","Tip":false}"
+ string nontipQueryStr = JsonSerializer.Serialize(nonTipQuery, Serialization.serializationOptions);
using (var redis = ConnectionMultiplexer.Connect("localhost"))
{
@@ -139,7 +139,7 @@ public void SendingSecondAndThirdLimitOrderMakesNonTipQueryWorkAfter()
var values = db.StringGet(nontipQueryStr);
Assert.That(String.IsNullOrEmpty(values), Is.False,
"should have nontip tail(not null) in this market");
- var orders = JsonConvert.DeserializeObject>(values);
+ var orders = JsonSerializer.Deserialize>(values, Serialization.serializationOptions);
Assert.That(orders.Count, Is.EqualTo(2),
"should have nontip tail of 2 elements in this market now");
@@ -156,7 +156,7 @@ public void SendingSecondAndThirdLimitOrderMakesNonTipQueryWorkAfter()
Assert.That(order2.IsNull, Is.EqualTo(false),
"should have the second order content(not null)");
var secondLimitOrderSerialized =
- JsonConvert.SerializeObject(secondLimitOrder);
+ JsonSerializer.Serialize(secondLimitOrder, Serialization.serializationOptions);
Assert.That(order2.ToString(),
Is.EqualTo(secondLimitOrderSerialized),
"received second order should have same content");
@@ -167,7 +167,7 @@ public void SendingSecondAndThirdLimitOrderMakesNonTipQueryWorkAfter()
Assert.That(order3.IsNull, Is.EqualTo(false),
"should have the third order content(not null)");
var thirdLimitOrderSerialized =
- JsonConvert.SerializeObject(thirdLimitOrder);
+ JsonSerializer.Serialize(thirdLimitOrder, Serialization.serializationOptions);
Assert.That(order3.ToString(),
Is.EqualTo(thirdLimitOrderSerialized),
"received second order should have same content");
@@ -198,8 +198,8 @@ public void TipIsReplaced()
var nonTipQuery = new MarketQuery(market, side, false);
- //e.g. {"Market":{"BuyCurrency":{"Case":"BTC"},"SellCurrency":{"Case":"USD"}},"Side":{"Case":"Buy"},"Tip":true}"
- string nontipQueryStr = JsonConvert.SerializeObject(nonTipQuery);
+ //e.g. {"Market":{"BuyCurrency":"BTC","SellCurrency":"USD"},"Side":"Bid","Tip":false}"
+ string nontipQueryStr = JsonSerializer.Serialize(nonTipQuery, Serialization.serializationOptions);
using (var redis = ConnectionMultiplexer.Connect("localhost"))
{
@@ -208,7 +208,7 @@ public void TipIsReplaced()
var values = db.StringGet(nontipQueryStr);
Assert.That(String.IsNullOrEmpty(values), Is.False,
"should have nontip tail(not null) in this market");
- var orders = JsonConvert.DeserializeObject>(values);
+ var orders = JsonSerializer.Deserialize>(values, Serialization.serializationOptions);
Assert.That(orders.Count, Is.EqualTo(1),
"should have nontip tail of 2 elements in this market now");
@@ -222,7 +222,7 @@ public void TipIsReplaced()
Assert.That(theOrder.IsNull, Is.EqualTo(false),
"should have the second order content(not null)");
var firstLimitOrderSerialized =
- JsonConvert.SerializeObject(firstLimitOrder);
+ JsonSerializer.Serialize(firstLimitOrder, Serialization.serializationOptions);
Assert.That(theOrder.ToString(),
Is.EqualTo(firstLimitOrderSerialized),
"received second order should have same content");