diff --git a/AspNetCore.sln b/AspNetCore.sln
index 81801038c953..e07978a7aba5 100644
--- a/AspNetCore.sln
+++ b/AspNetCore.sln
@@ -1626,6 +1626,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.SpaSer
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MinimalSample", "src\Http\samples\MinimalSample\MinimalSample.csproj", "{9647D8B7-4616-4E05-B258-BAD5CAEEDD38}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.Extensions", "Microsoft.Extensions", "{DFDE077C-D574-4A7C-B646-B79131397EA7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Extensions.Features", "src\Http\Microsoft.Extensions\src\Microsoft.Extensions.Features.csproj", "{30FBE063-E56D-4688-8F7C-EE8183C16E9C}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -7709,6 +7713,18 @@ Global
{9647D8B7-4616-4E05-B258-BAD5CAEEDD38}.Release|x64.Build.0 = Release|Any CPU
{9647D8B7-4616-4E05-B258-BAD5CAEEDD38}.Release|x86.ActiveCfg = Release|Any CPU
{9647D8B7-4616-4E05-B258-BAD5CAEEDD38}.Release|x86.Build.0 = Release|Any CPU
+ {30FBE063-E56D-4688-8F7C-EE8183C16E9C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {30FBE063-E56D-4688-8F7C-EE8183C16E9C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {30FBE063-E56D-4688-8F7C-EE8183C16E9C}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {30FBE063-E56D-4688-8F7C-EE8183C16E9C}.Debug|x64.Build.0 = Debug|Any CPU
+ {30FBE063-E56D-4688-8F7C-EE8183C16E9C}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {30FBE063-E56D-4688-8F7C-EE8183C16E9C}.Debug|x86.Build.0 = Debug|Any CPU
+ {30FBE063-E56D-4688-8F7C-EE8183C16E9C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {30FBE063-E56D-4688-8F7C-EE8183C16E9C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {30FBE063-E56D-4688-8F7C-EE8183C16E9C}.Release|x64.ActiveCfg = Release|Any CPU
+ {30FBE063-E56D-4688-8F7C-EE8183C16E9C}.Release|x64.Build.0 = Release|Any CPU
+ {30FBE063-E56D-4688-8F7C-EE8183C16E9C}.Release|x86.ActiveCfg = Release|Any CPU
+ {30FBE063-E56D-4688-8F7C-EE8183C16E9C}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -8514,6 +8530,8 @@ Global
{DF4637DA-5F07-4903-8461-4E2DAB235F3C} = {7F99E967-3DC1-4198-9D55-47CD9471D0B6}
{AAB50C64-39AA-4AED-8E9C-50D68E7751AD} = {7F99E967-3DC1-4198-9D55-47CD9471D0B6}
{9647D8B7-4616-4E05-B258-BAD5CAEEDD38} = {EB5E294B-9ED5-43BF-AFA9-1CD2327F3DC1}
+ {DFDE077C-D574-4A7C-B646-B79131397EA7} = {627BE8B3-59E6-4F1D-8C9C-76B804D41724}
+ {30FBE063-E56D-4688-8F7C-EE8183C16E9C} = {DFDE077C-D574-4A7C-B646-B79131397EA7}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3E8720B3-DBDD-498C-B383-2CC32A054E8F}
diff --git a/eng/ProjectReferences.props b/eng/ProjectReferences.props
index a0a18b9d018a..19cdcf0767ab 100644
--- a/eng/ProjectReferences.props
+++ b/eng/ProjectReferences.props
@@ -30,6 +30,7 @@
+
diff --git a/eng/SharedFramework.Local.props b/eng/SharedFramework.Local.props
index 49d28f78f0f2..089ba2d62380 100644
--- a/eng/SharedFramework.Local.props
+++ b/eng/SharedFramework.Local.props
@@ -15,6 +15,7 @@
+
diff --git a/src/Http/Http.Features/src/Microsoft.AspNetCore.Http.Features.csproj b/src/Http/Http.Features/src/Microsoft.AspNetCore.Http.Features.csproj
index 29f075d6dc70..59b70b6c1837 100644
--- a/src/Http/Http.Features/src/Microsoft.AspNetCore.Http.Features.csproj
+++ b/src/Http/Http.Features/src/Microsoft.AspNetCore.Http.Features.csproj
@@ -10,9 +10,10 @@
enable
-
+
+
diff --git a/src/Http/Http.Features/src/PublicAPI.Shipped.txt b/src/Http/Http.Features/src/PublicAPI.Shipped.txt
index f97bf2426e2e..e537b32ce364 100644
--- a/src/Http/Http.Features/src/PublicAPI.Shipped.txt
+++ b/src/Http/Http.Features/src/PublicAPI.Shipped.txt
@@ -20,15 +20,6 @@ Microsoft.AspNetCore.Http.CookieOptions.Secure.set -> void
Microsoft.AspNetCore.Http.Features.Authentication.IHttpAuthenticationFeature
Microsoft.AspNetCore.Http.Features.Authentication.IHttpAuthenticationFeature.User.get -> System.Security.Claims.ClaimsPrincipal?
Microsoft.AspNetCore.Http.Features.Authentication.IHttpAuthenticationFeature.User.set -> void
-Microsoft.AspNetCore.Http.Features.FeatureCollection
-Microsoft.AspNetCore.Http.Features.FeatureCollection.FeatureCollection() -> void
-Microsoft.AspNetCore.Http.Features.FeatureCollection.FeatureCollection(Microsoft.AspNetCore.Http.Features.IFeatureCollection! defaults) -> void
-Microsoft.AspNetCore.Http.Features.FeatureCollection.Get() -> TFeature?
-Microsoft.AspNetCore.Http.Features.FeatureCollection.GetEnumerator() -> System.Collections.Generic.IEnumerator>!
-Microsoft.AspNetCore.Http.Features.FeatureCollection.IsReadOnly.get -> bool
-Microsoft.AspNetCore.Http.Features.FeatureCollection.Set(TFeature instance) -> void
-Microsoft.AspNetCore.Http.Features.FeatureCollection.this[System.Type! key].get -> object?
-Microsoft.AspNetCore.Http.Features.FeatureCollection.this[System.Type! key].set -> void
Microsoft.AspNetCore.Http.Features.FeatureReference
Microsoft.AspNetCore.Http.Features.FeatureReference.Fetch(Microsoft.AspNetCore.Http.Features.IFeatureCollection! features) -> T?
Microsoft.AspNetCore.Http.Features.FeatureReference.Update(Microsoft.AspNetCore.Http.Features.IFeatureCollection! features, T feature) -> T
@@ -45,13 +36,6 @@ Microsoft.AspNetCore.Http.Features.HttpsCompressionMode
Microsoft.AspNetCore.Http.Features.HttpsCompressionMode.Compress = 2 -> Microsoft.AspNetCore.Http.Features.HttpsCompressionMode
Microsoft.AspNetCore.Http.Features.HttpsCompressionMode.Default = 0 -> Microsoft.AspNetCore.Http.Features.HttpsCompressionMode
Microsoft.AspNetCore.Http.Features.HttpsCompressionMode.DoNotCompress = 1 -> Microsoft.AspNetCore.Http.Features.HttpsCompressionMode
-Microsoft.AspNetCore.Http.Features.IFeatureCollection
-Microsoft.AspNetCore.Http.Features.IFeatureCollection.Get() -> TFeature
-Microsoft.AspNetCore.Http.Features.IFeatureCollection.IsReadOnly.get -> bool
-Microsoft.AspNetCore.Http.Features.IFeatureCollection.Revision.get -> int
-Microsoft.AspNetCore.Http.Features.IFeatureCollection.Set(TFeature instance) -> void
-Microsoft.AspNetCore.Http.Features.IFeatureCollection.this[System.Type! key].get -> object?
-Microsoft.AspNetCore.Http.Features.IFeatureCollection.this[System.Type! key].set -> void
Microsoft.AspNetCore.Http.Features.IFormFeature
Microsoft.AspNetCore.Http.Features.IFormFeature.Form.get -> Microsoft.AspNetCore.Http.IFormCollection?
Microsoft.AspNetCore.Http.Features.IFormFeature.Form.set -> void
@@ -242,6 +226,5 @@ Microsoft.AspNetCore.Http.SameSiteMode.Unspecified = -1 -> Microsoft.AspNetCore.
Microsoft.AspNetCore.Http.WebSocketAcceptContext
Microsoft.AspNetCore.Http.WebSocketAcceptContext.WebSocketAcceptContext() -> void
static readonly Microsoft.AspNetCore.Http.Features.FeatureReference.Default -> Microsoft.AspNetCore.Http.Features.FeatureReference
-virtual Microsoft.AspNetCore.Http.Features.FeatureCollection.Revision.get -> int
virtual Microsoft.AspNetCore.Http.WebSocketAcceptContext.SubProtocol.get -> string?
virtual Microsoft.AspNetCore.Http.WebSocketAcceptContext.SubProtocol.set -> void
diff --git a/src/Http/Http.Features/src/PublicAPI.Unshipped.txt b/src/Http/Http.Features/src/PublicAPI.Unshipped.txt
index 5b914c27b50f..39845687d635 100644
--- a/src/Http/Http.Features/src/PublicAPI.Unshipped.txt
+++ b/src/Http/Http.Features/src/PublicAPI.Unshipped.txt
@@ -9,9 +9,5 @@
*REMOVED*Microsoft.AspNetCore.Http.Features.IHttpSendFileFeature.SendFileAsync(string! path, long offset, long? count, System.Threading.CancellationToken cancellation) -> System.Threading.Tasks.Task!
*REMOVED*Microsoft.AspNetCore.Http.Features.IServerVariablesFeature.this[string! variableName].get -> string!
*REMOVED*Microsoft.AspNetCore.Http.ISession.TryGetValue(string! key, out byte[]! value) -> bool
-Microsoft.AspNetCore.Http.Features.FeatureCollection.Set(TFeature? instance) -> void
-Microsoft.AspNetCore.Http.Features.IFeatureCollection.Get() -> TFeature?
-Microsoft.AspNetCore.Http.Features.IFeatureCollection.Set(TFeature? instance) -> void
Microsoft.AspNetCore.Http.Features.IServerVariablesFeature.this[string! variableName].get -> string?
Microsoft.AspNetCore.Http.ISession.TryGetValue(string! key, out byte[]? value) -> bool
-Microsoft.AspNetCore.Http.Features.FeatureCollection.FeatureCollection(int initialCapacity) -> void
\ No newline at end of file
diff --git a/src/Http/Http/src/DefaultHttpContext.cs b/src/Http/Http/src/DefaultHttpContext.cs
index 9143938a7496..9a31801abc0b 100644
--- a/src/Http/Http/src/DefaultHttpContext.cs
+++ b/src/Http/Http/src/DefaultHttpContext.cs
@@ -6,6 +6,7 @@
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.IO;
+using System.Runtime.CompilerServices;
using System.Security.Claims;
using System.Threading;
using Microsoft.AspNetCore.Http.Features;
diff --git a/src/Http/HttpAbstractions.slnf b/src/Http/HttpAbstractions.slnf
index 2b9c64391b89..829f660a41d9 100644
--- a/src/Http/HttpAbstractions.slnf
+++ b/src/Http/HttpAbstractions.slnf
@@ -17,6 +17,7 @@
"src\\Http\\Http.Extensions\\src\\Microsoft.AspNetCore.Http.Extensions.csproj",
"src\\Http\\Http.Extensions\\test\\Microsoft.AspNetCore.Http.Extensions.Tests.csproj",
"src\\Http\\Http.Features\\src\\Microsoft.AspNetCore.Http.Features.csproj",
+ "src\\Http\\Microsoft.Extensions\\src\\Microsoft.Extensions.Features.csproj",
"src\\Http\\Http.Features\\test\\Microsoft.AspNetCore.Http.Features.Tests.csproj",
"src\\Http\\Http\\perf\\Microbenchmarks\\Microsoft.AspNetCore.Http.Microbenchmarks.csproj",
"src\\Http\\Http\\src\\Microsoft.AspNetCore.Http.csproj",
diff --git a/src/Http/Http.Features/src/FeatureCollection.cs b/src/Http/Microsoft.Extensions/src/FeatureCollection.cs
similarity index 98%
rename from src/Http/Http.Features/src/FeatureCollection.cs
rename to src/Http/Microsoft.Extensions/src/FeatureCollection.cs
index 7bde54632dfb..b9e641045395 100644
--- a/src/Http/Http.Features/src/FeatureCollection.cs
+++ b/src/Http/Microsoft.Extensions/src/FeatureCollection.cs
@@ -5,12 +5,14 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
+using System.Runtime.CompilerServices;
namespace Microsoft.AspNetCore.Http.Features
{
///
/// Default implementation for .
///
+ [TypeForwardedFrom("Microsoft.AspNetCore.Http")]
public class FeatureCollection : IFeatureCollection
{
private static readonly KeyComparer FeatureKeyComparer = new KeyComparer();
diff --git a/src/Http/Http.Features/src/IFeatureCollection.cs b/src/Http/Microsoft.Extensions/src/IFeatureCollection.cs
similarity index 94%
rename from src/Http/Http.Features/src/IFeatureCollection.cs
rename to src/Http/Microsoft.Extensions/src/IFeatureCollection.cs
index ff1f3ec69676..5064c9e5e73a 100644
--- a/src/Http/Http.Features/src/IFeatureCollection.cs
+++ b/src/Http/Microsoft.Extensions/src/IFeatureCollection.cs
@@ -3,12 +3,14 @@
using System;
using System.Collections.Generic;
+using System.Runtime.CompilerServices;
namespace Microsoft.AspNetCore.Http.Features
{
///
/// Represents a collection of HTTP features.
///
+ [TypeForwardedFrom("Microsoft.AspNetCore.Http")]
public interface IFeatureCollection : IEnumerable>
{
///
diff --git a/src/Http/Microsoft.Extensions/src/Microsoft.Extensions.Features.csproj b/src/Http/Microsoft.Extensions/src/Microsoft.Extensions.Features.csproj
new file mode 100644
index 000000000000..cfb7df575cd2
--- /dev/null
+++ b/src/Http/Microsoft.Extensions/src/Microsoft.Extensions.Features.csproj
@@ -0,0 +1,17 @@
+
+
+
+ netstandard2.0
+
+
+
+ ASP.NET Core extensions for HTTP feature.
+ $(DefaultNetFxTargetFramework);netstandard2.0;$(DefaultNetCoreTargetFramework)
+ $(DefaultNetCoreTargetFramework)
+ true
+ true
+ aspnetcore
+ enable
+
+
+
diff --git a/src/Http/Microsoft.Extensions/src/PublicAPI.Shipped.txt b/src/Http/Microsoft.Extensions/src/PublicAPI.Shipped.txt
new file mode 100644
index 000000000000..b39dee22603c
--- /dev/null
+++ b/src/Http/Microsoft.Extensions/src/PublicAPI.Shipped.txt
@@ -0,0 +1,19 @@
+#nullable enable
+Microsoft.AspNetCore.Http.Features.IFeatureCollection
+Microsoft.AspNetCore.Http.Features.IFeatureCollection.Get() -> TFeature?
+Microsoft.AspNetCore.Http.Features.IFeatureCollection.IsReadOnly.get -> bool
+Microsoft.AspNetCore.Http.Features.IFeatureCollection.Revision.get -> int
+Microsoft.AspNetCore.Http.Features.IFeatureCollection.Set(TFeature? instance) -> void
+Microsoft.AspNetCore.Http.Features.IFeatureCollection.this[System.Type! key].get -> object?
+Microsoft.AspNetCore.Http.Features.IFeatureCollection.this[System.Type! key].set -> void
+Microsoft.AspNetCore.Http.Features.FeatureCollection
+Microsoft.AspNetCore.Http.Features.FeatureCollection.FeatureCollection() -> void
+Microsoft.AspNetCore.Http.Features.FeatureCollection.FeatureCollection(Microsoft.AspNetCore.Http.Features.IFeatureCollection! defaults) -> void
+Microsoft.AspNetCore.Http.Features.FeatureCollection.FeatureCollection(int initialCapacity) -> void
+Microsoft.AspNetCore.Http.Features.FeatureCollection.Get() -> TFeature?
+Microsoft.AspNetCore.Http.Features.FeatureCollection.GetEnumerator() -> System.Collections.Generic.IEnumerator>!
+Microsoft.AspNetCore.Http.Features.FeatureCollection.IsReadOnly.get -> bool
+Microsoft.AspNetCore.Http.Features.FeatureCollection.Set(TFeature? instance) -> void
+Microsoft.AspNetCore.Http.Features.FeatureCollection.this[System.Type! key].get -> object?
+Microsoft.AspNetCore.Http.Features.FeatureCollection.this[System.Type! key].set -> void
+virtual Microsoft.AspNetCore.Http.Features.FeatureCollection.Revision.get -> int
diff --git a/src/Http/Microsoft.Extensions/src/PublicAPI.Unshipped.txt b/src/Http/Microsoft.Extensions/src/PublicAPI.Unshipped.txt
new file mode 100644
index 000000000000..7dc5c58110bf
--- /dev/null
+++ b/src/Http/Microsoft.Extensions/src/PublicAPI.Unshipped.txt
@@ -0,0 +1 @@
+#nullable enable