Skip to content

Commit

Permalink
Cache JsonSerializerOptions
Browse files Browse the repository at this point in the history
According to dotnet/runtime#65396, using a new JsonSerializerOptions every time JsonSerializer is invoked is a suboptimal pattern.

Fix this by caching JsonSerializerOptions instances.
  • Loading branch information
eerhardt committed Jun 13, 2023
1 parent 3169a93 commit fd76f39
Show file tree
Hide file tree
Showing 10 changed files with 34 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ public async Task<OrderData> GetOrderDraftFromBasketAsync(BasketData basket)

var ordersDraftResponse = await response.Content.ReadAsStringAsync();

return JsonSerializer.Deserialize<OrderData>(ordersDraftResponse, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});
return JsonSerializer.Deserialize<OrderData>(ordersDraftResponse, JsonHelper.CaseInsensitiveOptions);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ public async Task<OrderData> GetOrderDraftFromBasketAsync(BasketData basket)

var ordersDraftResponse = await response.Content.ReadAsStringAsync();

return JsonSerializer.Deserialize<OrderData>(ordersDraftResponse, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});
return JsonSerializer.Deserialize<OrderData>(ordersDraftResponse, JsonHelper.CaseInsensitiveOptions);
}
}
10 changes: 5 additions & 5 deletions src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ public class EventBusRabbitMQ : IEventBus, IDisposable
{
const string BROKER_NAME = "eshop_event_bus";

private static readonly JsonSerializerOptions s_indentedOptions = new() { WriteIndented = true };
private static readonly JsonSerializerOptions s_caseInsensitiveOptions = new() { PropertyNameCaseInsensitive = true };

private readonly IRabbitMQPersistentConnection _persistentConnection;
private readonly ILogger<EventBusRabbitMQ> _logger;
private readonly IEventBusSubscriptionsManager _subsManager;
Expand Down Expand Up @@ -69,10 +72,7 @@ public void Publish(IntegrationEvent @event)

channel.ExchangeDeclare(exchange: BROKER_NAME, type: "direct");

var body = JsonSerializer.SerializeToUtf8Bytes(@event, @event.GetType(), new JsonSerializerOptions
{
WriteIndented = true
});
var body = JsonSerializer.SerializeToUtf8Bytes(@event, @event.GetType(), s_indentedOptions);

policy.Execute(() =>
{
Expand Down Expand Up @@ -256,7 +256,7 @@ private async Task ProcessEvent(string eventName, string message)
var handler = scope.ServiceProvider.GetService(subscription.HandlerType);
if (handler == null) continue;
var eventType = _subsManager.GetEventTypeByName(eventName);
var integrationEvent = JsonSerializer.Deserialize(message, eventType, new JsonSerializerOptions() { PropertyNameCaseInsensitive = true });
var integrationEvent = JsonSerializer.Deserialize(message, eventType, s_caseInsensitiveOptions);
var concreteType = typeof(IIntegrationEventHandler<>).MakeGenericType(eventType);

await Task.Yield();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@

public class IntegrationEventLogEntry
{
private static readonly JsonSerializerOptions s_indentedOptions = new() { WriteIndented = true };
private static readonly JsonSerializerOptions s_caseInsensitiveOptions = new() { PropertyNameCaseInsensitive = true };

private IntegrationEventLogEntry() { }
public IntegrationEventLogEntry(IntegrationEvent @event, Guid transactionId)
{
EventId = @event.Id;
CreationTime = @event.CreationDate;
EventTypeName = @event.GetType().FullName;
Content = JsonSerializer.Serialize(@event, @event.GetType(), new JsonSerializerOptions
{
WriteIndented = true
});
Content = JsonSerializer.Serialize(@event, @event.GetType(), s_indentedOptions);
State = EventStateEnum.NotPublished;
TimesSent = 0;
TransactionId = transactionId.ToString();
Expand All @@ -30,7 +30,7 @@ public IntegrationEventLogEntry(IntegrationEvent @event, Guid transactionId)

public IntegrationEventLogEntry DeserializeJsonContent(Type type)
{
IntegrationEvent = JsonSerializer.Deserialize(Content, type, new JsonSerializerOptions() { PropertyNameCaseInsensitive = true }) as IntegrationEvent;
IntegrationEvent = JsonSerializer.Deserialize(Content, type, s_caseInsensitiveOptions) as IntegrationEvent;
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,20 @@ public async Task<CustomerBasket> GetBasketAsync(string customerId)
return null;
}

return JsonSerializer.Deserialize<CustomerBasket>(data, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});
return JsonSerializer.Deserialize<CustomerBasket>(data, JsonHelper.CaseInsensitiveOptions);
}

public async Task<CustomerBasket> UpdateBasketAsync(CustomerBasket basket)
{
var created = await _database.StringSetAsync(basket.BuyerId, JsonSerializer.Serialize(basket));
var created = await _database.StringSetAsync(basket.BuyerId, JsonSerializer.Serialize(basket, JsonHelper.CaseInsensitiveOptions));

if (!created)
{
_logger.LogInformation("Problem occur persisting the item.");
return null;
}

_logger.LogInformation("Basket item persisted succesfully.");
_logger.LogInformation("Basket item persisted successfully.");

return await GetBasketAsync(basket.BuyerId);
}
Expand Down
12 changes: 12 additions & 0 deletions src/Services/Services.Common/JsonHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Text.Json;

namespace Services.Common
{
public static class JsonHelper
{
public static readonly JsonSerializerOptions CaseInsensitiveOptions = new()
{
PropertyNameCaseInsensitive = true
};
}
}
15 changes: 3 additions & 12 deletions src/Web/WebMVC/Services/BasketService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,7 @@ public async Task<Basket> GetBasket(ApplicationUser user)
var responseString = await response.Content.ReadAsStringAsync();
return string.IsNullOrEmpty(responseString) ?
new Basket() { BuyerId = user.Id } :
JsonSerializer.Deserialize<Basket>(responseString, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});
JsonSerializer.Deserialize<Basket>(responseString, JsonHelper.CaseInsensitiveOptions);
}

public async Task<Basket> UpdateBasket(Basket basket)
Expand Down Expand Up @@ -82,10 +79,7 @@ public async Task<Basket> SetQuantities(ApplicationUser user, Dictionary<string,

var jsonResponse = await response.Content.ReadAsStringAsync();

return JsonSerializer.Deserialize<Basket>(jsonResponse, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});
return JsonSerializer.Deserialize<Basket>(jsonResponse, JsonHelper.CaseInsensitiveOptions);
}

public async Task<Order> GetOrderDraft(string basketId)
Expand All @@ -94,10 +88,7 @@ public async Task<Order> GetOrderDraft(string basketId)

var responseString = await _apiClient.GetStringAsync(uri);

var response = JsonSerializer.Deserialize<Order>(responseString, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});
var response = JsonSerializer.Deserialize<Order>(responseString, JsonHelper.CaseInsensitiveOptions);

return response;
}
Expand Down
5 changes: 1 addition & 4 deletions src/Web/WebMVC/Services/CatalogService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@ public async Task<Catalog> GetCatalogItems(int page, int take, int? brand, int?

var responseString = await _httpClient.GetStringAsync(uri);

var catalog = JsonSerializer.Deserialize<Catalog>(responseString, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});
var catalog = JsonSerializer.Deserialize<Catalog>(responseString, JsonHelper.CaseInsensitiveOptions);

return catalog;
}
Expand Down
10 changes: 2 additions & 8 deletions src/Web/WebMVC/Services/OrderingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@ async public Task<Order> GetOrder(ApplicationUser user, string id)

var responseString = await _httpClient.GetStringAsync(uri);

var response = JsonSerializer.Deserialize<Order>(responseString, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});
var response = JsonSerializer.Deserialize<Order>(responseString, JsonHelper.CaseInsensitiveOptions);

return response;
}
Expand All @@ -37,10 +34,7 @@ async public Task<List<Order>> GetMyOrders(ApplicationUser user)

var responseString = await _httpClient.GetStringAsync(uri);

var response = JsonSerializer.Deserialize<List<Order>>(responseString, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});
var response = JsonSerializer.Deserialize<List<Order>>(responseString, JsonHelper.CaseInsensitiveOptions);

return response;
}
Expand Down
5 changes: 1 addition & 4 deletions src/Web/WebhookClient/Services/WebhooksClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ public async Task<IEnumerable<WebhookResponse>> LoadWebhooks()
var client = _httpClientFactory.CreateClient("GrantClient");
var response = await client.GetAsync(_options.WebhooksUrl + "/api/v1/webhooks");
var json = await response.Content.ReadAsStringAsync();
var subscriptions = JsonSerializer.Deserialize<IEnumerable<WebhookResponse>>(json, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});
var subscriptions = JsonSerializer.Deserialize<IEnumerable<WebhookResponse>>(json, JsonHelper.CaseInsensitiveOptions);
return subscriptions;
}
}

0 comments on commit fd76f39

Please sign in to comment.