using Azure.Core.Serialization; using Microsoft.Azure.Cosmos; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System; using System.Collections.Concurrent; using System.Text.Json; using System.Text.Json.Serialization; using System.IO; using System.Threading.Tasks; namespace TEAMModelOS.SDK.DI { public class AzureCosmosFactory { private readonly IServiceProvider _services; private readonly IOptionsMonitor _optionsMonitor; private readonly ILogger _logger; //private Option _option; private ConcurrentDictionary CosmosClients { get; } = new ConcurrentDictionary(); // private CosmosDatabase database { get; set; } public AzureCosmosFactory(IServiceProvider services, IOptionsMonitor optionsMonitor, ILogger logger) { if (services == null) throw new ArgumentNullException(nameof(services)); if (optionsMonitor == null) throw new ArgumentNullException(nameof(optionsMonitor)); _services = services; _optionsMonitor = optionsMonitor; _logger = logger; } /// /// 取得CosmosClient,支持安全執行緒 /// /// /// 可以使用Regions.{區域}設置,指定此屬性後,SDK會首選該區域來執行操作。此外,SDK會自動選擇後備的地理複製區域以實現高可用性。如果未指定此屬性,則SDK會將寫區域用作所有操作的首選區域 /// public CosmosClient GetCosmosClient(string? region = null, string name = "Default") { try { //CosmosClientOptions 的 SerializerOptions = new CosmosSerializationOptions() { PropertyNamingPolicy = CosmosPropertyNamingPolicy.CamelCase } //需等待官方修正 JsonSerializerOptions jsonSerializerOptions = new JsonSerializerOptions() { // DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }; var cm = CosmosClients.GetOrAdd(name, x => new CosmosClient(_optionsMonitor.Get(name).CosmosConnectionString, new CosmosClientOptions() { Serializer= new CosmosSystemTextJsonSerializer(jsonSerializerOptions), ApplicationRegion = region })); return cm; } catch (Exception e) { _logger?.LogWarning(e, e.Message); throw; } } } /// /// Uses which leverages System.Text.Json providing a simple API to interact with on the Azure SDKs. /// // public class CosmosSystemTextJsonSerializer : CosmosSerializer { private readonly JsonSerializerOptions _serializerOptions; public CosmosSystemTextJsonSerializer(JsonSerializerOptions jsonSerializerOptions) { this._serializerOptions = jsonSerializerOptions; } public override T FromStream(Stream stream) { using (stream) { if (typeof(Stream).IsAssignableFrom(typeof(T))) { return (T)(object)stream; } return JsonSerializer.Deserialize(stream, _serializerOptions); } } public override Stream ToStream(T input) { var outputStream = new MemoryStream(); JsonSerializer.Serialize(outputStream, input, _serializerOptions); // A BREAKPOINT HERE AND A LOOK INSIDE 'outputStream' shows that ALL the fields have been serialized EXCEPT 'Id' or 'id. outputStream.Position = 0; return outputStream; } } // }