Rename IContentSerializer to IHttpContentSerializer and related methods to better reflect what it does

This commit is contained in:
Claire Novotny 2021-02-04 17:27:16 -05:00
Родитель 70047e1d77
Коммит 0dd5a2293c
Не удалось извлечь подпись
12 изменённых файлов: 54 добавлений и 54 удалений

Просмотреть файл

@ -291,7 +291,7 @@ Task CreateUser([Body(buffered: true)] User user);
#### JSON content
JSON requests and responses are serialized/deserialized using an instance of the `IContentSerializer` interface. Refit provides two implementations out of the box: `SystemTextJsonContentSerializer` (which is the default JSON serializer) and `NewtonsoftJsonContentSerializer`. The first uses `System.Text.Json` APIs and is focused on high performance and low memory usage, while the latter uss the known `Newtonsoft.Json` library and is more versatile and customizable. You can read more about the two serializers and the main differences between the two [at this link](https://docs.microsoft.com/dotnet/standard/serialization/system-text-json-migrate-from-newtonsoft-how-to).
JSON requests and responses are serialized/deserialized using an instance of the `IHttpContentSerializer` interface. Refit provides two implementations out of the box: `SystemTextJsonContentSerializer` (which is the default JSON serializer) and `NewtonsoftJsonContentSerializer`. The first uses `System.Text.Json` APIs and is focused on high performance and low memory usage, while the latter uss the known `Newtonsoft.Json` library and is more versatile and customizable. You can read more about the two serializers and the main differences between the two [at this link](https://docs.microsoft.com/dotnet/standard/serialization/system-text-json-migrate-from-newtonsoft-how-to).
For instance, here is how to create a new `RefitSettings` instance using the `Newtonsoft.Json`-based serializer (you'll also need to add a `PackageReference` to `Refit.Newtonsoft.Json`):

Просмотреть файл

@ -11,9 +11,9 @@ using Newtonsoft.Json;
namespace Refit
{
/// <summary>
/// A <see langword="class"/> implementing <see cref="IContentSerializer"/> using the Newtonsoft.Json APIs
/// A <see langword="class"/> implementing <see cref="IHttpContentSerializer"/> using the Newtonsoft.Json APIs
/// </summary>
public sealed class NewtonsoftJsonContentSerializer : IContentSerializer
public sealed class NewtonsoftJsonContentSerializer : IHttpContentSerializer
{
/// <summary>
/// The <see cref="Lazy{T}"/> instance providing the JSON serialization settings to use
@ -37,15 +37,15 @@ namespace Refit
}
/// <inheritdoc/>
public Task<HttpContent> SerializeAsync<T>(T item)
public HttpContent ToHttpContent<T>(T item)
{
var content = new StringContent(JsonConvert.SerializeObject(item, jsonSerializerSettings.Value), Encoding.UTF8, "application/json");
return Task.FromResult((HttpContent)content);
return content;
}
/// <inheritdoc/>
public async Task<T?> DeserializeAsync<T>(HttpContent content, CancellationToken cancellationToken = default)
public async Task<T?> FromHttpContentAsync<T>(HttpContent content, CancellationToken cancellationToken = default)
{
var serializer = JsonSerializer.Create(jsonSerializerSettings.Value);

Просмотреть файл

@ -554,9 +554,9 @@ namespace Refit.Tests
[InlineData(typeof(XmlContentSerializer), "application/xml")]
public async Task MultipartUploadShouldWorkWithAnObject(Type contentSerializerType, string mediaType)
{
if (Activator.CreateInstance(contentSerializerType) is not IContentSerializer serializer)
if (Activator.CreateInstance(contentSerializerType) is not IHttpContentSerializer serializer)
{
throw new ArgumentException($"{contentSerializerType.FullName} does not implement {nameof(IContentSerializer)}");
throw new ArgumentException($"{contentSerializerType.FullName} does not implement {nameof(IHttpContentSerializer)}");
}
var model1 = new ModelObject
@ -576,7 +576,7 @@ namespace Refit.Tests
Assert.Equal("theObject", parts[0].Headers.ContentDisposition.Name);
Assert.Null(parts[0].Headers.ContentDisposition.FileName);
Assert.Equal(mediaType, parts[0].Headers.ContentType.MediaType);
var result0 = await serializer.DeserializeAsync<ModelObject>(parts[0]).ConfigureAwait(false);
var result0 = await serializer.FromHttpContentAsync<ModelObject>(parts[0]).ConfigureAwait(false);
Assert.Equal(model1.Property1, result0.Property1);
Assert.Equal(model1.Property2, result0.Property2);
}
@ -598,9 +598,9 @@ namespace Refit.Tests
[InlineData(typeof(XmlContentSerializer), "application/xml")]
public async Task MultipartUploadShouldWorkWithObjects(Type contentSerializerType, string mediaType)
{
if (Activator.CreateInstance(contentSerializerType) is not IContentSerializer serializer)
if (Activator.CreateInstance(contentSerializerType) is not IHttpContentSerializer serializer)
{
throw new ArgumentException($"{contentSerializerType.FullName} does not implement {nameof(IContentSerializer)}");
throw new ArgumentException($"{contentSerializerType.FullName} does not implement {nameof(IHttpContentSerializer)}");
}
var model1 = new ModelObject
@ -625,7 +625,7 @@ namespace Refit.Tests
Assert.Equal("theObjects", parts[0].Headers.ContentDisposition.Name);
Assert.Null(parts[0].Headers.ContentDisposition.FileName);
Assert.Equal(mediaType, parts[0].Headers.ContentType.MediaType);
var result0 = await serializer.DeserializeAsync<ModelObject>(parts[0]).ConfigureAwait(false);
var result0 = await serializer.FromHttpContentAsync<ModelObject>(parts[0]).ConfigureAwait(false);
Assert.Equal(model1.Property1, result0.Property1);
Assert.Equal(model1.Property2, result0.Property2);
@ -633,7 +633,7 @@ namespace Refit.Tests
Assert.Equal("theObjects", parts[1].Headers.ContentDisposition.Name);
Assert.Null(parts[1].Headers.ContentDisposition.FileName);
Assert.Equal(mediaType, parts[1].Headers.ContentType.MediaType);
var result1 = await serializer.DeserializeAsync<ModelObject>(parts[1]).ConfigureAwait(false);
var result1 = await serializer.FromHttpContentAsync<ModelObject>(parts[1]).ConfigureAwait(false);
Assert.Equal(model2.Property1, result1.Property1);
Assert.Equal(model2.Property2, result1.Property2);
}

Просмотреть файл

@ -17,9 +17,9 @@ namespace Refit.Tests
[InlineData(typeof(XmlContentSerializer))]
public async Task WhenARequestRequiresABodyThenItDoesNotDeadlock(Type contentSerializerType)
{
if (Activator.CreateInstance(contentSerializerType) is not IContentSerializer serializer)
if (Activator.CreateInstance(contentSerializerType) is not IHttpContentSerializer serializer)
{
throw new ArgumentException($"{contentSerializerType.FullName} does not implement {nameof(IContentSerializer)}");
throw new ArgumentException($"{contentSerializerType.FullName} does not implement {nameof(IHttpContentSerializer)}");
}
var handler = new MockPushStreamContentHttpMessageHandler
@ -45,9 +45,9 @@ namespace Refit.Tests
[InlineData(typeof(XmlContentSerializer))]
public async Task WhenARequestRequiresABodyThenItIsSerialized(Type contentSerializerType)
{
if (Activator.CreateInstance(contentSerializerType) is not IContentSerializer serializer)
if (Activator.CreateInstance(contentSerializerType) is not IHttpContentSerializer serializer)
{
throw new ArgumentException($"{contentSerializerType.FullName} does not implement {nameof(IContentSerializer)}");
throw new ArgumentException($"{contentSerializerType.FullName} does not implement {nameof(IHttpContentSerializer)}");
}
var model = new User
@ -62,7 +62,7 @@ namespace Refit.Tests
Asserts = async content =>
{
var stringContent = new StringContent(await content.ReadAsStringAsync().ConfigureAwait(false));
var user = await serializer.DeserializeAsync<User>(content).ConfigureAwait(false);
var user = await serializer.FromHttpContentAsync<User>(content).ConfigureAwait(false);
Assert.NotSame(model, user);
Assert.Equal(model.Name, user.Name);
Assert.Equal(model.CreatedAt, user.CreatedAt);
@ -136,9 +136,9 @@ namespace Refit.Tests
var serializer = new SystemTextJsonContentSerializer();
var json = await serializer.SerializeAsync(model);
var json = serializer.ToHttpContent(model);
var result = await serializer.DeserializeAsync<TestAliasObject>(json);
var result = await serializer.FromHttpContentAsync<TestAliasObject>(json);
Assert.NotNull(result);
Assert.Equal(model.ShortNameForAlias, result.ShortNameForAlias);
@ -146,7 +146,7 @@ namespace Refit.Tests
}
[Fact]
public async Task StreamDeserialization_UsingSystemTextJsonContentSerializer_SetsCorrectHeaders()
public void StreamDeserialization_UsingSystemTextJsonContentSerializer_SetsCorrectHeaders()
{
var model = new TestAliasObject
{
@ -156,7 +156,7 @@ namespace Refit.Tests
var serializer = new SystemTextJsonContentSerializer();
var json = await serializer.SerializeAsync(model);
var json = serializer.ToHttpContent(model);
Assert.NotNull(json.Headers.ContentType);
Assert.Equal("utf-8", json.Headers.ContentType.CharSet);

Просмотреть файл

@ -22,12 +22,12 @@ namespace Refit.Tests
}
[Fact]
public async Task MediaTypeShouldBeApplicationXmlAsync()
public void MediaTypeShouldBeApplicationXmlAsync()
{
var dto = BuildDto();
var sut = new XmlContentSerializer();
var content = await sut.SerializeAsync(dto);
var content = sut.ToHttpContent(dto);
Assert.Equal("application/xml", content.Headers.ContentType.MediaType);
}
@ -38,7 +38,7 @@ namespace Refit.Tests
var dto = BuildDto();
var sut = new XmlContentSerializer();
var content = await sut.SerializeAsync(dto);
var content = sut.ToHttpContent(dto);
var document = new XmlDocument();
document.LoadXml(await content.ReadAsStringAsync());
@ -59,7 +59,7 @@ namespace Refit.Tests
serializerSettings.XmlAttributeOverrides.Add(dto.GetType(), attributes);
var sut = new XmlContentSerializer(serializerSettings);
var content = await sut.SerializeAsync(dto);
var content = sut.ToHttpContent(dto);
var document = new XmlDocument();
document.LoadXml(await content.ReadAsStringAsync());
@ -76,7 +76,7 @@ namespace Refit.Tests
serializerSettings.XmlNamespaces.Add(prefix, "https://google.com");
var sut = new XmlContentSerializer(serializerSettings);
var content = await sut.SerializeAsync(dto);
var content = sut.ToHttpContent(dto);
var document = new XmlDocument();
document.LoadXml(await content.ReadAsStringAsync());
@ -89,7 +89,7 @@ namespace Refit.Tests
var serializerSettings = new XmlContentSerializerSettings { XmlNamespaces = new XmlSerializerNamespaces() };
var sut = new XmlContentSerializer(serializerSettings);
var dto = await sut.DeserializeAsync<Dto>(new StringContent("<Dto><Identifier>123</Identifier></Dto>"));
var dto = await sut.FromHttpContentAsync<Dto>(new StringContent("<Dto><Identifier>123</Identifier></Dto>"));
Assert.Equal("123", dto.Identifier);
}
@ -111,7 +111,7 @@ namespace Refit.Tests
var sut = new XmlContentSerializer(serializerSettings);
var dto = BuildDto();
var content = await sut.SerializeAsync(dto);
var content = sut.ToHttpContent(dto);
var xml = XDocument.Parse(await content.ReadAsStringAsync());
var documentEncoding = xml.Declaration.Encoding;
Assert.Equal(encoding.WebName, documentEncoding);

Просмотреть файл

@ -39,7 +39,7 @@ namespace Refit
}
public async Task<T?> GetContentAsAsync<T>() => HasContent ?
await RefitSettings.ContentSerializer.DeserializeAsync<T>(new StringContent(Content!)).ConfigureAwait(false) :
await RefitSettings.ContentSerializer.FromHttpContentAsync<T>(new StringContent(Content!)).ConfigureAwait(false) :
default;
#pragma warning disable VSTHRD200 // Use "Async" suffix for async methods

Просмотреть файл

@ -19,7 +19,7 @@ namespace Refit
readonly IList<KeyValuePair<string?, string?>> formEntries = new List<KeyValuePair<string?, string?>>();
readonly IContentSerializer contentSerializer;
readonly IHttpContentSerializer contentSerializer;
public FormValueMultimap(object source, RefitSettings settings)
{

Просмотреть файл

@ -9,14 +9,14 @@ using System.Threading.Tasks;
namespace Refit
{
[Obsolete("Use NewtonsoftJsonContentSerializer in the Refit.Newtonsoft.Json package instead", true)]
public class JsonContentSerializer : IContentSerializer
public class JsonContentSerializer : IHttpContentSerializer
{
public Task<HttpContent> SerializeAsync<T>(T item)
public HttpContent ToHttpContent<T>(T item)
{
throw new NotImplementedException();
}
public Task<T?> DeserializeAsync<T>(HttpContent content, CancellationToken cancellationToken = default)
public Task<T?> FromHttpContentAsync<T>(HttpContent content, CancellationToken cancellationToken = default)
{
throw new NotImplementedException();
}

Просмотреть файл

@ -27,11 +27,11 @@ namespace Refit
/// <summary>
/// Creates a new <see cref="RefitSettings"/> instance with the specified parameters
/// </summary>
/// <param name="contentSerializer">The <see cref="IContentSerializer"/> instance to use</param>
/// <param name="contentSerializer">The <see cref="IHttpContentSerializer"/> instance to use</param>
/// <param name="urlParameterFormatter">The <see cref="IUrlParameterFormatter"/> instance to use (defaults to <see cref="DefaultUrlParameterFormatter"/>)</param>
/// <param name="formUrlEncodedParameterFormatter">The <see cref="IFormUrlEncodedParameterFormatter"/> instance to use (defaults to <see cref="DefaultFormUrlEncodedParameterFormatter"/>)</param>
public RefitSettings(
IContentSerializer contentSerializer,
IHttpContentSerializer contentSerializer,
IUrlParameterFormatter? urlParameterFormatter = null,
IFormUrlEncodedParameterFormatter? formUrlEncodedParameterFormatter = null)
{
@ -62,18 +62,18 @@ namespace Refit
/// </summary>
public Func<HttpResponseMessage, Task<Exception?>> ExceptionFactory { get; set; }
public IContentSerializer ContentSerializer { get; set; }
public IHttpContentSerializer ContentSerializer { get; set; }
public IUrlParameterFormatter UrlParameterFormatter { get; set; }
public IFormUrlEncodedParameterFormatter FormUrlEncodedParameterFormatter { get; set; }
public CollectionFormat CollectionFormat { get; set; } = CollectionFormat.RefitParameterFormatter;
public bool Buffered { get; set; } = true;
}
public interface IContentSerializer
public interface IHttpContentSerializer
{
Task<HttpContent> SerializeAsync<T>(T item);
HttpContent ToHttpContent<T>(T item);
Task<T?> DeserializeAsync<T>(HttpContent content, CancellationToken cancellationToken = default);
Task<T?> FromHttpContentAsync<T>(HttpContent content, CancellationToken cancellationToken = default);
/// <summary>
/// Calculates what the field name should be for the given property. This may be affected by custom attributes the serializer understands

Просмотреть файл

@ -31,7 +31,7 @@ namespace Refit
};
readonly Dictionary<string, List<RestMethodInfo>> interfaceHttpMethods;
readonly ConcurrentDictionary<CloseGenericMethodKey, RestMethodInfo> interfaceGenericHttpMethods;
readonly IContentSerializer serializer;
readonly IHttpContentSerializer serializer;
readonly RefitSettings settings;
public Type TargetType { get; }
@ -222,7 +222,7 @@ namespace Refit
Exception e;
try
{
multiPartContent.Add(await settings.ContentSerializer.SerializeAsync(itemValue).ConfigureAwait(false), parameterName);
multiPartContent.Add(settings.ContentSerializer.ToHttpContent(itemValue), parameterName);
return;
}
catch (Exception ex)
@ -321,7 +321,7 @@ namespace Refit
}
else
{
result = await serializer.DeserializeAsync<T>(content, cancellationToken).ConfigureAwait(false);
result = await serializer.FromHttpContentAsync<T>(content, cancellationToken).ConfigureAwait(false);
}
return result;
}
@ -570,7 +570,7 @@ namespace Refit
case BodySerializationMethod.Json:
#pragma warning restore CS0618 // Type or member is obsolete
case BodySerializationMethod.Serialized:
var content = await serializer.SerializeAsync(param).ConfigureAwait(false);
var content = serializer.ToHttpContent(param);
switch (restMethod.BodyParameterInfo.Item2)
{
case false:

Просмотреть файл

@ -17,9 +17,9 @@ using Refit.Buffers;
namespace Refit
{
/// <summary>
/// A <see langword="class"/> implementing <see cref="IContentSerializer"/> using the System.Text.Json APIs
/// A <see langword="class"/> implementing <see cref="IHttpContentSerializer"/> using the System.Text.Json APIs
/// </summary>
public sealed class SystemTextJsonContentSerializer : IContentSerializer
public sealed class SystemTextJsonContentSerializer : IHttpContentSerializer
{
/// <summary>
/// The JSON serialization options to use
@ -50,15 +50,15 @@ namespace Refit
}
/// <inheritdoc/>
public Task<HttpContent> SerializeAsync<T>(T item)
public HttpContent ToHttpContent<T>(T item)
{
var content = JsonContent.Create(item, options: jsonSerializerOptions);
var content = JsonContent.Create(item, options: jsonSerializerOptions);
return Task.FromResult<HttpContent>(content);
return content;
}
/// <inheritdoc/>
public async Task<T?> DeserializeAsync<T>(HttpContent content, CancellationToken cancellationToken = default)
public async Task<T?> FromHttpContentAsync<T>(HttpContent content, CancellationToken cancellationToken = default)
{
var item = await content.ReadFromJsonAsync<T>(jsonSerializerOptions, cancellationToken).ConfigureAwait(false);
return item;

Просмотреть файл

@ -13,7 +13,7 @@ using System.Xml.Serialization;
namespace Refit
{
public class XmlContentSerializer : IContentSerializer
public class XmlContentSerializer : IHttpContentSerializer
{
readonly XmlContentSerializerSettings settings;
readonly ConcurrentDictionary<Type, XmlSerializer> serializerCache = new();
@ -27,7 +27,7 @@ namespace Refit
this.settings = settings ?? throw new ArgumentNullException(nameof(settings));
}
public Task<HttpContent> SerializeAsync<T>(T item)
public HttpContent ToHttpContent<T>(T item)
{
if (item is null) throw new ArgumentNullException(nameof(item));
@ -39,10 +39,10 @@ namespace Refit
xmlSerializer.Serialize(writer, item, settings.XmlNamespaces);
var str = encoding.GetString(stream.ToArray());
var content = new StringContent(str, encoding, "application/xml");
return Task.FromResult((HttpContent)content);
return content;
}
public async Task<T?> DeserializeAsync<T>(HttpContent content, CancellationToken cancellationToken = default)
public async Task<T?> FromHttpContentAsync<T>(HttpContent content, CancellationToken cancellationToken = default)
{
var xmlSerializer = serializerCache.GetOrAdd(typeof(T), t => new XmlSerializer(
t,