Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement asynchronous support in ODataJsonLightSerializer #2030

Merged
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
1 change: 1 addition & 0 deletions src/Microsoft.OData.Core/ContainerBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ public static IContainerBuilder AddDefaultODataServices(this IContainerBuilder b

builder.AddService<IJsonReaderFactory, DefaultJsonReaderFactory>(ServiceLifetime.Singleton);
builder.AddService<IJsonWriterFactory>(ServiceLifetime.Singleton, sp => new DefaultJsonWriterFactory());
builder.AddService<IJsonWriterFactoryAsync>(ServiceLifetime.Singleton, sp => new DefaultJsonWriterFactory());
builder.AddService(ServiceLifetime.Singleton, sp => ODataMediaTypeResolver.GetMediaTypeResolver(null));
builder.AddService<ODataMessageInfo>(ServiceLifetime.Scoped);
builder.AddServicePrototype(new ODataMessageReaderSettings());
Expand Down
243 changes: 236 additions & 7 deletions src/Microsoft.OData.Core/Json/JsonLightInstanceAnnotationWriter.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ namespace Microsoft.OData.JsonLight
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Threading.Tasks;
using Microsoft.OData.Buffers;
using Microsoft.OData.Edm;
using Microsoft.OData.Json;
#endregion Namespaces
Expand Down Expand Up @@ -53,6 +52,9 @@ internal sealed class ODataJsonLightOutputContext : ODataOutputContext
/// <remarks>This field is also used to determine if the output context has been disposed already.</remarks>
private IJsonWriter jsonWriter;

/// <summary>The asynchronous JSON writer to write to.</summary>
private IJsonWriterAsync asynchronousJsonWriter;

/// <summary>
/// The oracle to use to determine the type name to write for entries and values.
/// </summary>
Expand Down Expand Up @@ -96,6 +98,7 @@ public ODataJsonLightOutputContext(
// COMPAT 2: JSON indentation - WCFDS indents only partially, it inserts newlines but doesn't actually insert spaces for indentation
// in here we allow the user to specify if true indentation should be used or if the limited functionality is enough.
this.jsonWriter = CreateJsonWriter(this.Container, this.textWriter, messageInfo.MediaType.HasIeee754CompatibleSetToTrue(), messageWriterSettings);
this.asynchronousJsonWriter = CreateAsynchronousJsonWriter(this.Container, this.textWriter, messageInfo.MediaType.HasIeee754CompatibleSetToTrue(), messageWriterSettings);
}
catch (Exception e)
{
Expand Down Expand Up @@ -133,6 +136,7 @@ internal ODataJsonLightOutputContext(
this.textWriter = textWriter;
bool ieee754CompatibleSetToTrue = (messageInfo.MediaType != null) ? messageInfo.MediaType.HasIeee754CompatibleSetToTrue() : false;
this.jsonWriter = CreateJsonWriter(messageInfo.Container, textWriter, ieee754CompatibleSetToTrue, messageWriterSettings);
this.asynchronousJsonWriter = CreateAsynchronousJsonWriter(messageInfo.Container, textWriter, ieee754CompatibleSetToTrue, messageWriterSettings);
this.metadataLevel = new JsonMinimalMetadataLevel();
this.propertyCacheHandler = new PropertyCacheHandler();
}
Expand All @@ -149,6 +153,18 @@ public IJsonWriter JsonWriter
}
}

/// <summary>
/// Returns the <see cref="JsonWriter"/> which is to be used to write the content of the message asynchronously.
/// </summary>
public IJsonWriterAsync AsynchronousJsonWriter
{
get
{
Debug.Assert(this.asynchronousJsonWriter != null, "Trying to get asynchronous JsonWriter while none is available.");
return this.asynchronousJsonWriter;
}
}

/// <summary>
/// Returns the oracle to use when determining the type name to write for entries and values.
/// </summary>
Expand Down Expand Up @@ -820,6 +836,29 @@ private static IJsonWriter CreateJsonWriter(IServiceProvider container, TextWrit
return jsonWriter;
}

private static IJsonWriterAsync CreateAsynchronousJsonWriter(IServiceProvider container, TextWriter textWriter, bool isIeee754Compatible, ODataMessageWriterSettings writerSettings)
{
IJsonWriterAsync asynchronousJsonWriter;
if (container == null)
{
asynchronousJsonWriter = new JsonWriter(textWriter, isIeee754Compatible);
}
else
{
IJsonWriterFactoryAsync asynchronousJsonWriterFactory = container.GetRequiredService<IJsonWriterFactoryAsync>();
asynchronousJsonWriter = asynchronousJsonWriterFactory.CreateAsynchronousJsonWriter(textWriter, isIeee754Compatible);
Debug.Assert(asynchronousJsonWriter != null, "asynchronousJsonWriter != null");
}

JsonWriter writer = asynchronousJsonWriter as JsonWriter;
if (writer != null && writerSettings.ArrayPool != null)
{
writer.ArrayPool = writerSettings.ArrayPool;
}

return asynchronousJsonWriter;
}

/// <summary>
/// Creates an <see cref="ODataWriter" /> to write a resource set.
/// </summary>
Expand Down
Loading