private CosmosSerializer GetSerializer <T>()
        {
            Type inputType = typeof(T);

            if (inputType == typeof(PatchSpec))
            {
                if (this.patchOperationSerializer == null)
                {
                    this.patchOperationSerializer = PatchOperationsJsonConverter.CreatePatchOperationsSerializer(
                        cosmosSerializer: this.customSerializer ?? new CosmosJsonDotNetSerializer(),
                        propertiesSerializer: CosmosSerializerCore.propertiesSerializer);
                }
                return(this.patchOperationSerializer);
            }

            if (this.customSerializer == null)
            {
                return(CosmosSerializerCore.propertiesSerializer);
            }

            if (inputType == typeof(AccountProperties) ||
                inputType == typeof(DatabaseProperties) ||
                inputType == typeof(ContainerProperties) ||
                inputType == typeof(PermissionProperties) ||
                inputType == typeof(StoredProcedureProperties) ||
                inputType == typeof(TriggerProperties) ||
                inputType == typeof(UserDefinedFunctionProperties) ||
                inputType == typeof(UserProperties) ||
                inputType == typeof(ConflictProperties) ||
                inputType == typeof(ThroughputProperties) ||
                inputType == typeof(OfferV2) ||
                inputType == typeof(ClientEncryptionKeyProperties) ||
                inputType == typeof(PartitionedQueryExecutionInfo))
            {
                return(CosmosSerializerCore.propertiesSerializer);
            }

            if (inputType == typeof(SqlQuerySpec))
            {
                throw new ArgumentException("SqlQuerySpec to stream must use the SqlQuerySpec override");
            }

#if DEBUG
            // This check is used to stop internal developers from deserializing an internal with the user's serialier that doesn't know how to materialize said type.
            string clientAssemblyName    = typeof(DatabaseProperties).Assembly.GetName().Name;
            string directAssemblyName    = typeof(Documents.PartitionKeyRange).Assembly.GetName().Name;
            string inputAssemblyName     = inputType.Assembly.GetName().Name;
            bool   inputIsClientOrDirect = string.Equals(inputAssemblyName, clientAssemblyName) || string.Equals(inputAssemblyName, directAssemblyName);
            bool   typeIsWhiteListed     = inputType == typeof(Document);

            if (!typeIsWhiteListed && inputIsClientOrDirect)
            {
                throw new ArgumentException($"User serializer is being used for internal type:{inputType.FullName}.");
            }
#endif

            return(this.customSerializer);
        }
 internal CosmosSerializerCore(
     CosmosSerializer customSerializer = null)
 {
     if (customSerializer == null)
     {
         this.customSerializer         = null;
         this.sqlQuerySpecSerializer   = null;
         this.patchOperationSerializer = null;
     }
     else
     {
         this.customSerializer       = new CosmosJsonSerializerWrapper(customSerializer);
         this.sqlQuerySpecSerializer = CosmosSqlQuerySpecJsonConverter.CreateSqlQuerySpecSerializer(
             cosmosSerializer: this.customSerializer,
             propertiesSerializer: CosmosSerializerCore.propertiesSerializer);
         this.patchOperationSerializer = PatchOperationsJsonConverter.CreatePatchOperationsSerializer(
             cosmosSerializer: this.customSerializer,
             propertiesSerializer: CosmosSerializerCore.propertiesSerializer);
     }
 }
 internal CosmosSerializerCore(
     CosmosSerializer customSerializer = null)
 {
     if (customSerializer == null)
     {
         this.customSerializer = null;
         // this would allow us to set the JsonConverter and inturn handle Serialized/Stream Query Parameter Value.
         this.sqlQuerySpecSerializer = CosmosSqlQuerySpecJsonConverter.CreateSqlQuerySpecSerializer(
             cosmosSerializer: null,
             propertiesSerializer: CosmosSerializerCore.propertiesSerializer);
         this.patchOperationSerializer = null;
     }
     else
     {
         this.customSerializer       = new CosmosJsonSerializerWrapper(customSerializer);
         this.sqlQuerySpecSerializer = CosmosSqlQuerySpecJsonConverter.CreateSqlQuerySpecSerializer(
             cosmosSerializer: this.customSerializer,
             propertiesSerializer: CosmosSerializerCore.propertiesSerializer);
         this.patchOperationSerializer = PatchOperationsJsonConverter.CreatePatchOperationsSerializer(
             cosmosSerializer: this.customSerializer,
             propertiesSerializer: CosmosSerializerCore.propertiesSerializer);
     }
 }