Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public ModelJsonConverter()
/// </summary>
/// <param name="format"> The format to serialize to and deserialize from. </param>
public ModelJsonConverter(ModelSerializerFormat format)
: this(new ModelSerializerOptions(format)) { }
: this(ModelSerializerOptions.GetOptions(format)) { }

/// <summary>
/// Initializes a new instance of <see cref="ModelJsonConverter"/>.
Expand Down
10 changes: 5 additions & 5 deletions sdk/core/Azure.Core/src/Serialization/ModelSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public static BinaryData Serialize<T>(T model, ModelSerializerOptions? options =
/// <returns>A <see cref="BinaryData"/> representation of the model in the <see cref="ModelSerializerFormat"/> specified by the <paramref name="format"/></returns>
public static BinaryData Serialize<T>(T model, ModelSerializerFormat format)
where T : IModelSerializable<T>
=> Serialize<T>(model, new ModelSerializerOptions(format));
=> Serialize<T>(model, ModelSerializerOptions.GetOptions(format));

/// <summary>
/// Converts the value of a model into a <see cref="BinaryData"/>.
Expand Down Expand Up @@ -67,7 +67,7 @@ public static BinaryData Serialize(object model, ModelSerializerOptions? options
/// <returns>A <see cref="BinaryData"/> representation of the model in the <see cref="ModelSerializerFormat"/> specified by the <paramref name="format"/></returns>
/// <exception cref="InvalidOperationException">Throws if <paramref name="model"/> does not implement <see cref="IModelSerializable{T}"/>.</exception>
public static BinaryData Serialize(object model, ModelSerializerFormat format)
=> Serialize(model, new ModelSerializerOptions(format));
=> Serialize(model, ModelSerializerOptions.GetOptions(format));

/// <summary>
/// Converts the <see cref="BinaryData"/> into a <typeparamref name="T"/>.
Expand All @@ -92,7 +92,7 @@ public static T Deserialize<T>(BinaryData data, ModelSerializerOptions? options
/// <exception cref="InvalidOperationException">Throws if <typeparamref name="T"/> does not have a public or internal default constructor.</exception>
public static T Deserialize<T>(BinaryData data, ModelSerializerFormat format)
where T : IModelSerializable<T>
=> Deserialize<T>(data, new ModelSerializerOptions(format));
=> Deserialize<T>(data, ModelSerializerOptions.GetOptions(format));

/// <summary>
/// Converts the <see cref="BinaryData"/> into a <paramref name="returnType"/>.
Expand Down Expand Up @@ -120,7 +120,7 @@ public static object Deserialize(BinaryData data, Type returnType, ModelSerializ
/// <exception cref="InvalidOperationException">Throws if <paramref name="returnType"/> does not implement <see cref="IModelSerializable{T}"/>.</exception>
/// <exception cref="InvalidOperationException">Throws if <paramref name="returnType"/> does not have a public or internal default constructor.</exception>
public static object Deserialize(BinaryData data, Type returnType, ModelSerializerFormat format)
=> Deserialize(data, returnType, new ModelSerializerOptions(format));
=> Deserialize(data, returnType, ModelSerializerOptions.GetOptions(format));

/// <summary>
/// Converts an <see cref="IModelJsonSerializable{T}"/> into a <see cref="BinaryData"/>.
Expand Down Expand Up @@ -149,7 +149,7 @@ public static BinaryData ConvertToBinaryData(IModelJsonSerializable<object> mode
/// <param name="format">The <see cref="ModelSerializerFormat"/> to use.</param>
/// <returns>A binary representation of the serialized model.</returns>
public static BinaryData ConvertToBinaryData(IModelJsonSerializable<object> model, ModelSerializerFormat format)
=> ConvertToBinaryData(model, new ModelSerializerOptions(format));
=> ConvertToBinaryData(model, ModelSerializerOptions.GetOptions(format));

private static IModelSerializable<object> GetInstance(Type returnType)
{
Expand Down
12 changes: 11 additions & 1 deletion sdk/core/Azure.Core/src/Serialization/ModelSerializerOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System;
using System.Collections.Generic;

namespace Azure.Core.Serialization
{
Expand All @@ -10,10 +11,19 @@ namespace Azure.Core.Serialization
/// </summary>
public class ModelSerializerOptions
{
private static readonly IReadOnlyDictionary<ModelSerializerFormat, ModelSerializerOptions> _singletonMap = new Dictionary<ModelSerializerFormat, ModelSerializerOptions>()
{
{ ModelSerializerFormat.Json, new ModelSerializerOptions(ModelSerializerFormat.Json, true) },
{ ModelSerializerFormat.Wire, new ModelSerializerOptions(ModelSerializerFormat.Wire, true) }
};

/// <summary>
/// Default options for serializing models into the format the Azure serivce is expecting.
/// </summary>
public static readonly ModelSerializerOptions DefaultWireOptions = new ModelSerializerOptions(ModelSerializerFormat.Wire, true);
public static readonly ModelSerializerOptions DefaultWireOptions = _singletonMap[ModelSerializerFormat.Wire];

internal static ModelSerializerOptions GetOptions(ModelSerializerFormat format)
=> _singletonMap.TryGetValue(format, out ModelSerializerOptions? options) ? options! : new ModelSerializerOptions(format);

private bool _isFrozen;
private Func<Type, ObjectSerializer>? _genericTypeSerializerCreator;
Expand Down
66 changes: 66 additions & 0 deletions sdk/core/Azure.Core/tests/ModelSerializerOptionsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using System.Reflection;
using Azure.Core.Serialization;
using NUnit.Framework;

namespace Azure.Core.Tests
{
internal class ModelSerializerOptionsTests
{
[Test]
public void ValidatePropertyIsFrozen() => ValidateFrozenInstance(ModelSerializerOptions.DefaultWireOptions);

[Test]
public void AllInstancesInMapShouldBeFrozen()
{
Dictionary<ModelSerializerFormat, ModelSerializerOptions> optionsDictionary = typeof(ModelSerializerOptions)
.GetField("_singletonMap", BindingFlags.NonPublic | BindingFlags.Static)
.GetValue(null) as Dictionary<ModelSerializerFormat, ModelSerializerOptions>;
foreach (var frozen in optionsDictionary.Values)
{
ValidateFrozenInstance(frozen);
}
}

public void ValidateFrozenInstance(ModelSerializerOptions frozen)
{
Assert.Throws<InvalidOperationException>(() => frozen.GenericTypeSerializerCreator = type => null);
}

[Test]
public void NewInstanceShouldNotBeFrozen()
{
ModelSerializerOptions nonFrozen = new ModelSerializerOptions();
Assert.DoesNotThrow(() => nonFrozen.GenericTypeSerializerCreator = type => null);
}

[Test]
public void MapAndStaticPropertySameObject()
{
Assert.IsTrue(ReferenceEquals(ModelSerializerOptions.DefaultWireOptions, ModelSerializerOptions.GetOptions(ModelSerializerFormat.Wire)));
}

[Test]
public void MapShouldReturnSingletons()
{
Assert.IsTrue(ReferenceEquals(ModelSerializerOptions.GetOptions(ModelSerializerFormat.Wire), ModelSerializerOptions.GetOptions(ModelSerializerFormat.Wire)));
Assert.IsTrue(ReferenceEquals(ModelSerializerOptions.GetOptions(ModelSerializerFormat.Json), ModelSerializerOptions.GetOptions(ModelSerializerFormat.Json)));
}

[Test]
public void MapShouldHaveRightValues()
{
var options = ModelSerializerOptions.GetOptions(ModelSerializerFormat.Wire);
Assert.AreEqual(ModelSerializerFormat.Wire, options.Format);
Assert.IsNull(options.GenericTypeSerializerCreator);

options = ModelSerializerOptions.GetOptions(ModelSerializerFormat.Json);
Assert.AreEqual(ModelSerializerFormat.Json, options.Format);
Assert.IsNull(options.GenericTypeSerializerCreator);
}
}
}
10 changes: 0 additions & 10 deletions sdk/core/Azure.Core/tests/ModelSerializerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,6 @@ namespace Azure.Core.Tests.ModelSerializationTests
{
public class ModelSerializerTests
{
[Test]
public void ValidateFrozenInstance()
{
ModelSerializerOptions frozen = ModelSerializerOptions.DefaultWireOptions;
ModelSerializerOptions nonFrozen = new ModelSerializerOptions();

Assert.Throws<InvalidOperationException>(() => frozen.GenericTypeSerializerCreator = type => null);
Assert.DoesNotThrow(() => nonFrozen.GenericTypeSerializerCreator = type => null);
}

[Test]
public void ValidateErrorIfUnknownDoesntExist()
{
Expand Down