Cache JsonSerializerOptions
According to https://github.com/dotnet/runtime/issues/65396, using a new JsonSerializerOptions every time JsonSerializer is invoked is a suboptimal pattern. Fix this by caching JsonSerializerOptions instances.
This commit is contained in:
		
							parent
							
								
									3169a93344
								
							
						
					
					
						commit
						fd76f390ef
					
				| @ -23,9 +23,6 @@ public class OrderApiClient : IOrderApiClient | |||||||
| 
 | 
 | ||||||
|         var ordersDraftResponse = await response.Content.ReadAsStringAsync(); |         var ordersDraftResponse = await response.Content.ReadAsStringAsync(); | ||||||
| 
 | 
 | ||||||
|         return JsonSerializer.Deserialize<OrderData>(ordersDraftResponse, new JsonSerializerOptions |         return JsonSerializer.Deserialize<OrderData>(ordersDraftResponse, JsonHelper.CaseInsensitiveOptions); | ||||||
|         { |  | ||||||
|             PropertyNameCaseInsensitive = true |  | ||||||
|         }); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -23,9 +23,6 @@ public class OrderApiClient : IOrderApiClient | |||||||
| 
 | 
 | ||||||
|         var ordersDraftResponse = await response.Content.ReadAsStringAsync(); |         var ordersDraftResponse = await response.Content.ReadAsStringAsync(); | ||||||
| 
 | 
 | ||||||
|         return JsonSerializer.Deserialize<OrderData>(ordersDraftResponse, new JsonSerializerOptions |         return JsonSerializer.Deserialize<OrderData>(ordersDraftResponse, JsonHelper.CaseInsensitiveOptions); | ||||||
|         { |  | ||||||
|             PropertyNameCaseInsensitive = true |  | ||||||
|         }); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -5,6 +5,9 @@ public class EventBusRabbitMQ : IEventBus, IDisposable | |||||||
| { | { | ||||||
|     const string BROKER_NAME = "eshop_event_bus"; |     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 IRabbitMQPersistentConnection _persistentConnection; | ||||||
|     private readonly ILogger<EventBusRabbitMQ> _logger; |     private readonly ILogger<EventBusRabbitMQ> _logger; | ||||||
|     private readonly IEventBusSubscriptionsManager _subsManager; |     private readonly IEventBusSubscriptionsManager _subsManager; | ||||||
| @ -69,10 +72,7 @@ public class EventBusRabbitMQ : IEventBus, IDisposable | |||||||
| 
 | 
 | ||||||
|         channel.ExchangeDeclare(exchange: BROKER_NAME, type: "direct"); |         channel.ExchangeDeclare(exchange: BROKER_NAME, type: "direct"); | ||||||
| 
 | 
 | ||||||
|         var body = JsonSerializer.SerializeToUtf8Bytes(@event, @event.GetType(), new JsonSerializerOptions |         var body = JsonSerializer.SerializeToUtf8Bytes(@event, @event.GetType(), s_indentedOptions); | ||||||
|         { |  | ||||||
|             WriteIndented = true |  | ||||||
|         }); |  | ||||||
| 
 | 
 | ||||||
|         policy.Execute(() => |         policy.Execute(() => | ||||||
|         { |         { | ||||||
| @ -256,7 +256,7 @@ public class EventBusRabbitMQ : IEventBus, IDisposable | |||||||
|                     var handler = scope.ServiceProvider.GetService(subscription.HandlerType); |                     var handler = scope.ServiceProvider.GetService(subscription.HandlerType); | ||||||
|                     if (handler == null) continue; |                     if (handler == null) continue; | ||||||
|                     var eventType = _subsManager.GetEventTypeByName(eventName); |                     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); |                     var concreteType = typeof(IIntegrationEventHandler<>).MakeGenericType(eventType); | ||||||
| 
 | 
 | ||||||
|                     await Task.Yield(); |                     await Task.Yield(); | ||||||
|  | |||||||
| @ -2,16 +2,16 @@ | |||||||
| 
 | 
 | ||||||
| public class IntegrationEventLogEntry | public class IntegrationEventLogEntry | ||||||
| { | { | ||||||
|  |     private static readonly JsonSerializerOptions s_indentedOptions = new() { WriteIndented = true }; | ||||||
|  |     private static readonly JsonSerializerOptions s_caseInsensitiveOptions = new() { PropertyNameCaseInsensitive = true }; | ||||||
|  | 
 | ||||||
|     private IntegrationEventLogEntry() { } |     private IntegrationEventLogEntry() { } | ||||||
|     public IntegrationEventLogEntry(IntegrationEvent @event, Guid transactionId) |     public IntegrationEventLogEntry(IntegrationEvent @event, Guid transactionId) | ||||||
|     { |     { | ||||||
|         EventId = @event.Id; |         EventId = @event.Id; | ||||||
|         CreationTime = @event.CreationDate; |         CreationTime = @event.CreationDate; | ||||||
|         EventTypeName = @event.GetType().FullName; |         EventTypeName = @event.GetType().FullName; | ||||||
|         Content = JsonSerializer.Serialize(@event, @event.GetType(), new JsonSerializerOptions |         Content = JsonSerializer.Serialize(@event, @event.GetType(), s_indentedOptions); | ||||||
|         { |  | ||||||
|             WriteIndented = true |  | ||||||
|         }); |  | ||||||
|         State = EventStateEnum.NotPublished; |         State = EventStateEnum.NotPublished; | ||||||
|         TimesSent = 0; |         TimesSent = 0; | ||||||
|         TransactionId = transactionId.ToString(); |         TransactionId = transactionId.ToString(); | ||||||
| @ -30,7 +30,7 @@ public class IntegrationEventLogEntry | |||||||
| 
 | 
 | ||||||
|     public IntegrationEventLogEntry DeserializeJsonContent(Type type) |     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; |         return this; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -35,15 +35,12 @@ public class RedisBasketRepository : IBasketRepository | |||||||
|             return null; |             return null; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         return JsonSerializer.Deserialize<CustomerBasket>(data, new JsonSerializerOptions |         return JsonSerializer.Deserialize<CustomerBasket>(data, JsonHelper.CaseInsensitiveOptions); | ||||||
|         { |  | ||||||
|             PropertyNameCaseInsensitive = true |  | ||||||
|         }); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public async Task<CustomerBasket> UpdateBasketAsync(CustomerBasket basket) |     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) |         if (!created) | ||||||
|         { |         { | ||||||
| @ -51,7 +48,7 @@ public class RedisBasketRepository : IBasketRepository | |||||||
|             return null; |             return null; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         _logger.LogInformation("Basket item persisted succesfully."); |         _logger.LogInformation("Basket item persisted successfully."); | ||||||
| 
 | 
 | ||||||
|         return await GetBasketAsync(basket.BuyerId); |         return await GetBasketAsync(basket.BuyerId); | ||||||
|     } |     } | ||||||
|  | |||||||
							
								
								
									
										12
									
								
								src/Services/Services.Common/JsonHelper.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/Services/Services.Common/JsonHelper.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | |||||||
|  | using System.Text.Json; | ||||||
|  | 
 | ||||||
|  | namespace Services.Common | ||||||
|  | { | ||||||
|  |     public static class JsonHelper | ||||||
|  |     { | ||||||
|  |         public static readonly JsonSerializerOptions CaseInsensitiveOptions = new() | ||||||
|  |         { | ||||||
|  |             PropertyNameCaseInsensitive = true | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -29,10 +29,7 @@ public class BasketService : IBasketService | |||||||
|         var responseString = await response.Content.ReadAsStringAsync(); |         var responseString = await response.Content.ReadAsStringAsync(); | ||||||
|         return string.IsNullOrEmpty(responseString) ? |         return string.IsNullOrEmpty(responseString) ? | ||||||
|             new Basket() { BuyerId = user.Id } : |             new Basket() { BuyerId = user.Id } : | ||||||
|             JsonSerializer.Deserialize<Basket>(responseString, new JsonSerializerOptions |             JsonSerializer.Deserialize<Basket>(responseString, JsonHelper.CaseInsensitiveOptions); | ||||||
|             { |  | ||||||
|                 PropertyNameCaseInsensitive = true |  | ||||||
|             }); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public async Task<Basket> UpdateBasket(Basket basket) |     public async Task<Basket> UpdateBasket(Basket basket) | ||||||
| @ -82,10 +79,7 @@ public class BasketService : IBasketService | |||||||
| 
 | 
 | ||||||
|         var jsonResponse = await response.Content.ReadAsStringAsync(); |         var jsonResponse = await response.Content.ReadAsStringAsync(); | ||||||
| 
 | 
 | ||||||
|         return JsonSerializer.Deserialize<Basket>(jsonResponse, new JsonSerializerOptions |         return JsonSerializer.Deserialize<Basket>(jsonResponse, JsonHelper.CaseInsensitiveOptions); | ||||||
|         { |  | ||||||
|             PropertyNameCaseInsensitive = true |  | ||||||
|         }); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public async Task<Order> GetOrderDraft(string basketId) |     public async Task<Order> GetOrderDraft(string basketId) | ||||||
| @ -94,10 +88,7 @@ public class BasketService : IBasketService | |||||||
| 
 | 
 | ||||||
|         var responseString = await _apiClient.GetStringAsync(uri); |         var responseString = await _apiClient.GetStringAsync(uri); | ||||||
| 
 | 
 | ||||||
|         var response = JsonSerializer.Deserialize<Order>(responseString, new JsonSerializerOptions |         var response = JsonSerializer.Deserialize<Order>(responseString, JsonHelper.CaseInsensitiveOptions); | ||||||
|         { |  | ||||||
|             PropertyNameCaseInsensitive = true |  | ||||||
|         }); |  | ||||||
| 
 | 
 | ||||||
|         return response; |         return response; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -23,10 +23,7 @@ public class CatalogService : ICatalogService | |||||||
| 
 | 
 | ||||||
|         var responseString = await _httpClient.GetStringAsync(uri); |         var responseString = await _httpClient.GetStringAsync(uri); | ||||||
| 
 | 
 | ||||||
|         var catalog = JsonSerializer.Deserialize<Catalog>(responseString, new JsonSerializerOptions |         var catalog = JsonSerializer.Deserialize<Catalog>(responseString, JsonHelper.CaseInsensitiveOptions); | ||||||
|         { |  | ||||||
|             PropertyNameCaseInsensitive = true |  | ||||||
|         }); |  | ||||||
| 
 | 
 | ||||||
|         return catalog; |         return catalog; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -23,10 +23,7 @@ public class OrderingService : IOrderingService | |||||||
| 
 | 
 | ||||||
|         var responseString = await _httpClient.GetStringAsync(uri); |         var responseString = await _httpClient.GetStringAsync(uri); | ||||||
| 
 | 
 | ||||||
|         var response = JsonSerializer.Deserialize<Order>(responseString, new JsonSerializerOptions |         var response = JsonSerializer.Deserialize<Order>(responseString, JsonHelper.CaseInsensitiveOptions); | ||||||
|         { |  | ||||||
|             PropertyNameCaseInsensitive = true |  | ||||||
|         }); |  | ||||||
| 
 | 
 | ||||||
|         return response; |         return response; | ||||||
|     } |     } | ||||||
| @ -37,10 +34,7 @@ public class OrderingService : IOrderingService | |||||||
| 
 | 
 | ||||||
|         var responseString = await _httpClient.GetStringAsync(uri); |         var responseString = await _httpClient.GetStringAsync(uri); | ||||||
| 
 | 
 | ||||||
|         var response = JsonSerializer.Deserialize<List<Order>>(responseString, new JsonSerializerOptions |         var response = JsonSerializer.Deserialize<List<Order>>(responseString, JsonHelper.CaseInsensitiveOptions); | ||||||
|         { |  | ||||||
|             PropertyNameCaseInsensitive = true |  | ||||||
|         }); |  | ||||||
| 
 | 
 | ||||||
|         return response; |         return response; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -14,10 +14,7 @@ public class WebhooksClient : IWebhooksClient | |||||||
|         var client = _httpClientFactory.CreateClient("GrantClient"); |         var client = _httpClientFactory.CreateClient("GrantClient"); | ||||||
|         var response = await client.GetAsync(_options.WebhooksUrl + "/api/v1/webhooks"); |         var response = await client.GetAsync(_options.WebhooksUrl + "/api/v1/webhooks"); | ||||||
|         var json = await response.Content.ReadAsStringAsync(); |         var json = await response.Content.ReadAsStringAsync(); | ||||||
|         var subscriptions = JsonSerializer.Deserialize<IEnumerable<WebhookResponse>>(json, new JsonSerializerOptions |         var subscriptions = JsonSerializer.Deserialize<IEnumerable<WebhookResponse>>(json, JsonHelper.CaseInsensitiveOptions); | ||||||
|         { |  | ||||||
|             PropertyNameCaseInsensitive = true |  | ||||||
|         }); |  | ||||||
|         return subscriptions; |         return subscriptions; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user