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

Current dotnet/extensions API Surface #4373

Closed
wants to merge 14 commits into from
Closed
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Assembly 'Microsoft.AspNetCore.Diagnostics.Middleware'

namespace Microsoft.AspNetCore.Builder;

public static class HttpLoggingApplicationBuilderExtensions
{
public static IApplicationBuilder UseHttpLoggingMiddleware(this IApplicationBuilder builder);
geeknoid marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Assembly 'Microsoft.AspNetCore.Diagnostics.Middleware'

namespace Microsoft.AspNetCore.Builder;

public static class RequestLatencyTelemetryApplicationBuilderExtensions
{
public static IApplicationBuilder UseRequestCheckpoint(this IApplicationBuilder builder);
public static IApplicationBuilder UseRequestLatencyTelemetry(this IApplicationBuilder builder);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Assembly 'Microsoft.AspNetCore.Diagnostics.Middleware'

namespace Microsoft.AspNetCore.Diagnostics.Latency;

public static class RequestCheckpointConstants
{
public const string ElapsedTillHeaders = "elthdr";
public const string ElapsedTillFinished = "eltltf";
public const string ElapsedTillPipelineExitMiddleware = "eltexm";
public const string ElapsedResponseProcessed = "eltrspproc";
public const string ElapsedTillEntryMiddleware = "eltenm";
}
geeknoid marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Assembly 'Microsoft.AspNetCore.Diagnostics.Middleware'

using System;
using System.Runtime.CompilerServices;
using Microsoft.Shared.Data.Validation;

namespace Microsoft.AspNetCore.Diagnostics.Latency;

public class RequestLatencyTelemetryOptions
{
[TimeSpan(1000)]
public TimeSpan LatencyDataExportTimeout { get; set; }
public RequestLatencyTelemetryOptions();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Assembly 'Microsoft.AspNetCore.Diagnostics.Middleware'

using System.Collections.Generic;
using System.Runtime.CompilerServices;

namespace Microsoft.AspNetCore.Diagnostics.Logging;

public static class HttpLoggingTagNames
{
public const string Duration = "duration";
public const string Host = "httpHost";
public const string Method = "httpMethod";
public const string Path = "httpPath";
public const string RequestHeaderPrefix = "httpRequestHeader_";
public const string ResponseHeaderPrefix = "httpResponseHeader_";
public const string RequestBody = "httpRequestBody";
public const string ResponseBody = "httpResponseBody";
public const string StatusCode = "httpStatusCode";
public static IReadOnlyList<string> DimensionNames { get; }
}
geeknoid marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Assembly 'Microsoft.AspNetCore.Diagnostics.Middleware'

using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Diagnostics.Enrichment;

namespace Microsoft.AspNetCore.Diagnostics.Logging;

public interface IHttpLogEnricher
{
void Enrich(IEnrichmentTagCollector collector, HttpRequest request, HttpResponse response);
}
geeknoid marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Assembly 'Microsoft.AspNetCore.Diagnostics.Middleware'

namespace Microsoft.AspNetCore.Diagnostics.Logging;

public enum IncomingPathLoggingMode
{
Formatted = 0,
Structured = 1
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Assembly 'Microsoft.AspNetCore.Diagnostics.Middleware'

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using Microsoft.Extensions.Compliance.Classification;
using Microsoft.Extensions.Http.Diagnostics;
using Microsoft.Shared.Data.Validation;

namespace Microsoft.AspNetCore.Diagnostics.Logging;

public class LoggingOptions
{
public bool LogRequestStart { get; set; }
public bool LogBody { get; set; }
public IncomingPathLoggingMode RequestPathLoggingMode { get; set; }
[Experimental("EXTEXP0003", UrlFormat = "https://aka.ms/dotnet-extensions-warnings/{0}")]
public HttpRouteParameterRedactionMode RequestPathParameterRedactionMode { get; set; }
[TimeSpan(1, 60000)]
public TimeSpan RequestBodyReadTimeout { get; set; }
[Range(1, 1572864)]
public int BodySizeLimit { get; set; }
[Required]
public IDictionary<string, DataClassification> RouteParameterDataClasses { get; set; }
[Required]
public IDictionary<string, DataClassification> RequestHeadersDataClasses { get; set; }
[Required]
public ISet<string> RequestBodyContentTypes { get; set; }
[Required]
public IDictionary<string, DataClassification> ResponseHeadersDataClasses { get; set; }
[Required]
public ISet<string> ResponseBodyContentTypes { get; set; }
[Experimental("EXTEXP0003", UrlFormat = "https://aka.ms/dotnet-extensions-warnings/{0}")]
[Required]
public ISet<string> ExcludePathStartsWith { get; set; }
public LoggingOptions();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Assembly 'Microsoft.AspNetCore.Diagnostics.Middleware'

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using Microsoft.Extensions.Compliance.Classification;

namespace Microsoft.AspNetCore.Diagnostics;

public class RequestHeadersLogEnricherOptions
{
[Required]
[Experimental("EXTEXP0003", UrlFormat = "https://aka.ms/dotnet-extensions-warnings/{0}")]
public IDictionary<string, DataClassification> HeadersDataClasses { get; set; }
public RequestHeadersLogEnricherOptions();
}
29 changes: 29 additions & 0 deletions API/NoDocs/Microsoft.AspNetCore.HeaderParsing/CommonHeaders.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Assembly 'Microsoft.AspNetCore.HeaderParsing'

using System;
using System.Collections.Generic;
using System.Net;
using Microsoft.Net.Http.Headers;

namespace Microsoft.AspNetCore.HeaderParsing;

public static class CommonHeaders
{
public static HeaderSetup<HostHeaderValue> Host { get; }
public static HeaderSetup<IReadOnlyList<MediaTypeHeaderValue>> Accept { get; }
public static HeaderSetup<IReadOnlyList<StringWithQualityHeaderValue>> AcceptEncoding { get; }
public static HeaderSetup<IReadOnlyList<StringWithQualityHeaderValue>> AcceptLanguage { get; }
public static HeaderSetup<CacheControlHeaderValue> CacheControl { get; }
public static HeaderSetup<ContentDispositionHeaderValue> ContentDisposition { get; }
public static HeaderSetup<MediaTypeHeaderValue> ContentType { get; }
public static HeaderSetup<IReadOnlyList<CookieHeaderValue>> Cookie { get; }
public static HeaderSetup<DateTimeOffset> Date { get; }
public static HeaderSetup<IReadOnlyList<EntityTagHeaderValue>> IfMatch { get; }
public static HeaderSetup<IReadOnlyList<EntityTagHeaderValue>> IfModifiedSince { get; }
public static HeaderSetup<IReadOnlyList<EntityTagHeaderValue>> IfNoneMatch { get; }
public static HeaderSetup<RangeConditionHeaderValue> IfRange { get; }
public static HeaderSetup<DateTimeOffset> IfUnmodifiedSince { get; }
public static HeaderSetup<RangeHeaderValue> Range { get; }
public static HeaderSetup<Uri> Referer { get; }
public static HeaderSetup<IReadOnlyList<IPAddress>> XForwardedFor { get; }
}
13 changes: 13 additions & 0 deletions API/NoDocs/Microsoft.AspNetCore.HeaderParsing/HeaderKey.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Assembly 'Microsoft.AspNetCore.HeaderParsing'

using System.Runtime.CompilerServices;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Primitives;

namespace Microsoft.AspNetCore.HeaderParsing;

public sealed class HeaderKey<T> where T : notnull
geeknoid marked this conversation as resolved.
Show resolved Hide resolved
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's nothing in this public API that enables a HeaderKey<T> to be constructed / populated (e.g. control what Name returns) from outside of this library, yet there's an interface that returns one of these. Does that mean that interface is also not intended for external implementation?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

App code gets an IHeaderRegistry from DI and then calls the Register function, getting back a HeaderKey instance. The HeaderKey is then used to query the value of the header for the life of the application.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. My question was more that there's no way for someone outside of this library to construct one of these and populate the Name, which means the only code that can implement an IHeaderRegistry to give back a meaningful HeaderKey is ours. Is that intended?

public string Name { get; }
public override string ToString();
}
12 changes: 12 additions & 0 deletions API/NoDocs/Microsoft.AspNetCore.HeaderParsing/HeaderParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Assembly 'Microsoft.AspNetCore.HeaderParsing'

using System.Diagnostics.CodeAnalysis;
using Microsoft.Extensions.Primitives;

namespace Microsoft.AspNetCore.HeaderParsing;

public abstract class HeaderParser<T> where T : notnull
{
public abstract bool TryParse(StringValues values, [NotNullWhen(true)] out T? result, [NotNullWhen(false)] out string? error);
protected HeaderParser();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Assembly 'Microsoft.AspNetCore.HeaderParsing'

using System;
using System.CodeDom.Compiler;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.ObjectPool;

namespace Microsoft.AspNetCore.HeaderParsing;

public sealed class HeaderParsingFeature
{
public bool TryGetHeaderValue<T>(HeaderKey<T> header, [NotNullWhen(true)] out T? value) where T : notnull;
public bool TryGetHeaderValue<T>(HeaderKey<T> header, [NotNullWhen(true)] out T? value, out ParsingResult result) where T : notnull;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Assembly 'Microsoft.AspNetCore.HeaderParsing'

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Runtime.CompilerServices;
using Microsoft.Extensions.Primitives;

namespace Microsoft.AspNetCore.HeaderParsing;

public class HeaderParsingOptions
geeknoid marked this conversation as resolved.
Show resolved Hide resolved
{
public IDictionary<string, StringValues> DefaultValues { get; set; }
[Range(0, int.MaxValue)]
public int DefaultMaxCachedValuesPerHeader { get; set; }
public IDictionary<string, int> MaxCachedValuesPerHeader { get; set; }
public HeaderParsingOptions();
}
16 changes: 16 additions & 0 deletions API/NoDocs/Microsoft.AspNetCore.HeaderParsing/HeaderSetup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Assembly 'Microsoft.AspNetCore.HeaderParsing'

using System;
using System.Runtime.CompilerServices;

namespace Microsoft.AspNetCore.HeaderParsing;

public class HeaderSetup<THeader> where THeader : notnull
{
public string HeaderName { get; }
public Type? ParserType { get; }
public HeaderParser<THeader>? ParserInstance { get; }
public bool Cacheable { get; }
public HeaderSetup(string headerName, Type parserType, bool cacheable = false);
public HeaderSetup(string headerName, HeaderParser<THeader> instance, bool cacheable = false);
}
21 changes: 21 additions & 0 deletions API/NoDocs/Microsoft.AspNetCore.HeaderParsing/HostHeaderValue.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Assembly 'Microsoft.AspNetCore.HeaderParsing'

using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;

namespace Microsoft.AspNetCore.HeaderParsing;

public readonly struct HostHeaderValue : IEquatable<HostHeaderValue>
{
public string Host { get; }
public int? Port { get; }
public HostHeaderValue(string host, int? port);
public static bool operator ==(HostHeaderValue left, HostHeaderValue right);
public static bool operator !=(HostHeaderValue left, HostHeaderValue right);
public static bool TryParse(string value, [NotNullWhen(true)] out HostHeaderValue result);
public bool Equals(HostHeaderValue other);
public override bool Equals(object? obj);
public override int GetHashCode();
public override string ToString();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Assembly 'Microsoft.AspNetCore.HeaderParsing'

namespace Microsoft.AspNetCore.HeaderParsing;

public interface IHeaderRegistry
{
HeaderKey<T> Register<T>(HeaderSetup<T> setup) where T : notnull;
}
10 changes: 10 additions & 0 deletions API/NoDocs/Microsoft.AspNetCore.HeaderParsing/ParsingResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Assembly 'Microsoft.AspNetCore.HeaderParsing'

namespace Microsoft.AspNetCore.HeaderParsing;

public enum ParsingResult
{
Success = 0,
Error = 1,
NotFound = 2
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Assembly 'Microsoft.AspNetCore.HeaderParsing'

using System.Diagnostics.CodeAnalysis;
using Microsoft.AspNetCore.HeaderParsing;

namespace Microsoft.AspNetCore.Http;

public static class HeaderParsingHttpRequestExtensions
{
public static HeaderParsingFeature GetHeaderParsing(this HttpRequest request);
public static bool TryGetHeaderValue<T>(this HttpRequest request, HeaderKey<T> header, [NotNullWhen(true)] out T? value) where T : notnull;
public static bool TryGetHeaderValue<T>(this HttpRequest request, HeaderKey<T> header, [NotNullWhen(true)] out T? value, out ParsingResult result) where T : notnull;
}
20 changes: 20 additions & 0 deletions API/NoDocs/Microsoft.AspNetCore.Testing/ServiceFakesExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Assembly 'Microsoft.AspNetCore.Testing'

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Security.Cryptography.X509Certificates;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.Extensions.Hosting;

namespace Microsoft.AspNetCore.Testing;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These extensions should be in the same namespace as their extended types, IWebHostBuilder and IHost (even if it means splitting the class). I'll take care of that.


public static class ServiceFakesExtensions
{
public static IWebHostBuilder UseFakeStartup(this IWebHostBuilder builder);
geeknoid marked this conversation as resolved.
Show resolved Hide resolved
public static IWebHostBuilder ListenHttpOnAnyPort(this IWebHostBuilder builder);
public static IWebHostBuilder ListenHttpsOnAnyPort(this IWebHostBuilder builder, X509Certificate2? sslCertificate = null);
public static HttpClient CreateClient(this IHost host, HttpMessageHandler? handler = null, Func<Uri, bool>? addressFilter = null);
public static IEnumerable<Uri> GetListenUris(this IHost host);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Assembly 'Microsoft.Extensions.AmbientMetadata.Application'

using System.ComponentModel.DataAnnotations;
using System.Runtime.CompilerServices;

namespace Microsoft.Extensions.AmbientMetadata;

public class ApplicationMetadata
geeknoid marked this conversation as resolved.
Show resolved Hide resolved
{
public string? DeploymentRing { get; set; }
public string? BuildVersion { get; set; }
[Required]
public string ApplicationName { get; set; }
[Required]
public string EnvironmentName { get; set; }
public ApplicationMetadata();
}
15 changes: 15 additions & 0 deletions API/NoDocs/Microsoft.Extensions.AsyncState/AsyncStateToken.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Assembly 'Microsoft.Extensions.AsyncState'

using System;
using System.Runtime.CompilerServices;

namespace Microsoft.Extensions.AsyncState;

public readonly struct AsyncStateToken : IEquatable<AsyncStateToken>
{
public override bool Equals(object? obj);
public bool Equals(AsyncStateToken other);
public override int GetHashCode();
public static bool operator ==(AsyncStateToken left, AsyncStateToken right);
public static bool operator !=(AsyncStateToken left, AsyncStateToken right);
}
12 changes: 12 additions & 0 deletions API/NoDocs/Microsoft.Extensions.AsyncState/IAsyncContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Assembly 'Microsoft.Extensions.AsyncState'

using System.Diagnostics.CodeAnalysis;

namespace Microsoft.Extensions.AsyncState;

public interface IAsyncContext<T> where T : notnull
stephentoub marked this conversation as resolved.
Show resolved Hide resolved
{
T? Get();
void Set(T? context);
bool TryGet([MaybeNullWhen(false)] out T? context);
}
12 changes: 12 additions & 0 deletions API/NoDocs/Microsoft.Extensions.AsyncState/IAsyncLocalContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Assembly 'Microsoft.Extensions.AsyncState'

using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;

namespace Microsoft.Extensions.AsyncState;

[Experimental("EXTEXP0006", UrlFormat = "https://aka.ms/dotnet-extensions-warnings/{0}")]
[EditorBrowsable(EditorBrowsableState.Never)]
geeknoid marked this conversation as resolved.
Show resolved Hide resolved
public interface IAsyncLocalContext<T> : IAsyncContext<T> where T : class
{
}
Loading