From 8d4bf31b9610a49ea234758e1eb4a214ed9f8a34 Mon Sep 17 00:00:00 2001 From: Taylor Southwick Date: Wed, 6 Nov 2024 14:09:57 -0800 Subject: [PATCH] Remove public constructor from HttpSessionState There was no public constructor for this on framework. This was added initially as a way to override the current session implementation. However, now it can be changed by setting `HttpContext.Features.Get().State` and it will be propagated in the session. This is a breaking change, but we're already doing that for a few other APIs for v2. This will help guide people to the recommended approach to override behavior. --- .../SessionState/HttpSessionState.cs | 11 ++--- .../HttpContextTests.cs | 1 - .../SessionState/HttpSessionStateTests.cs | 43 +++++++++++-------- 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters/SessionState/HttpSessionState.cs b/src/Microsoft.AspNetCore.SystemWebAdapters/SessionState/HttpSessionState.cs index b961716c99..1a2e60c314 100644 --- a/src/Microsoft.AspNetCore.SystemWebAdapters/SessionState/HttpSessionState.cs +++ b/src/Microsoft.AspNetCore.SystemWebAdapters/SessionState/HttpSessionState.cs @@ -11,19 +11,14 @@ namespace System.Web.SessionState; [Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1710:Identifiers should have correct suffix", Justification = Constants.ApiFromAspNet)] public class HttpSessionState : ICollection { - private readonly Func _state; + private readonly ISessionStateFeature _feature; internal HttpSessionState(ISessionStateFeature feature) { - _state = () => feature.State ?? throw new InvalidOperationException("Session state is no longer available"); + _feature = feature; } - public HttpSessionState(ISessionState container) - { - _state = () => container; - } - - internal ISessionState State => _state(); + internal ISessionState State => _feature.State ?? throw new InvalidOperationException("Session state is no longer available"); public string SessionID => State.SessionID; diff --git a/test/Microsoft.AspNetCore.SystemWebAdapters.Tests/HttpContextTests.cs b/test/Microsoft.AspNetCore.SystemWebAdapters.Tests/HttpContextTests.cs index 564739ad1d..4895ed53ce 100644 --- a/test/Microsoft.AspNetCore.SystemWebAdapters.Tests/HttpContextTests.cs +++ b/test/Microsoft.AspNetCore.SystemWebAdapters.Tests/HttpContextTests.cs @@ -144,7 +144,6 @@ public void NonClaimsPrincipalIsCopied() public void GetServiceReturnsExpected() { var coreContext = new DefaultHttpContext(); - coreContext.Features.Set(new HttpSessionState(new Mock().Object)); var context = new HttpContext(coreContext); var provider = (IServiceProvider)context; diff --git a/test/Microsoft.AspNetCore.SystemWebAdapters.Tests/SessionState/HttpSessionStateTests.cs b/test/Microsoft.AspNetCore.SystemWebAdapters.Tests/SessionState/HttpSessionStateTests.cs index 408983d6c9..ff7643144b 100644 --- a/test/Microsoft.AspNetCore.SystemWebAdapters.Tests/SessionState/HttpSessionStateTests.cs +++ b/test/Microsoft.AspNetCore.SystemWebAdapters.Tests/SessionState/HttpSessionStateTests.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Web.SessionState; using AutoFixture; +using Microsoft.AspNetCore.SystemWebAdapters.Features; using Moq; using Xunit; @@ -27,7 +28,7 @@ public void SessionId() var session = new Mock(); session.Setup(s => s.SessionID).Returns(id); - var state = new HttpSessionState(session.Object); + var state = CreateSession(session.Object); // Act var result = state.SessionID; @@ -42,7 +43,7 @@ public void Mode() // Arrange var session = new Mock(); - var state = new HttpSessionState(session.Object); + var state = CreateSession(session.Object); // Act var result = state.Mode; @@ -60,7 +61,7 @@ public void Count() var session = new Mock(); session.Setup(s => s.Count).Returns(count); - var state = new HttpSessionState(session.Object); + var state = CreateSession(session.Object); // Act var result = state.Count; @@ -78,7 +79,7 @@ public void IsReadOnly(bool isReadOnly) var session = new Mock(); session.Setup(s => s.IsReadOnly).Returns(isReadOnly); - var state = new HttpSessionState(session.Object); + var state = CreateSession(session.Object); // Act var result = state.IsReadOnly; @@ -96,7 +97,7 @@ public void IsNewSession(bool isNewSession) var session = new Mock(); session.Setup(s => s.IsNewSession).Returns(isNewSession); - var state = new HttpSessionState(session.Object); + var state = CreateSession(session.Object); // Act var result = state.IsNewSession; @@ -116,7 +117,7 @@ public void TimeOut() session.SetupProperty(s => s.Timeout); session.Object.Timeout = timeout1; - var state = new HttpSessionState(session.Object); + var state = CreateSession(session.Object); // Act var result = state.Timeout; @@ -136,7 +137,7 @@ public void IsSynchronized(bool isSynchronized) var session = new Mock(); session.Setup(s => s.IsSynchronized).Returns(isSynchronized); - var state = new HttpSessionState(session.Object); + var state = CreateSession(session.Object); // Act var result = state.IsSynchronized; @@ -153,7 +154,7 @@ public void SyncRoot() var session = new Mock(); session.Setup(s => s.SyncRoot).Returns(sync); - var state = new HttpSessionState(session.Object); + var state = CreateSession(session.Object); // Act var result = state.SyncRoot; @@ -169,7 +170,7 @@ public void Abandon() var session = new Mock(); session.SetupProperty(s => s.IsAbandoned); - var state = new HttpSessionState(session.Object); + var state = CreateSession(session.Object); // Act state.Abandon(); @@ -188,7 +189,7 @@ public void Get() var session = new Mock(); session.Setup(s => s[key]).Returns(value); - var state = new HttpSessionState(session.Object); + var state = CreateSession(session.Object); // Act var result = state[key]; @@ -206,7 +207,7 @@ public void Set() var session = new Mock(); - var state = new HttpSessionState(session.Object); + var state = CreateSession(session.Object); // Act state[key] = value; @@ -223,7 +224,7 @@ public void Add() var value = new object(); var session = new Mock(); - var state = new HttpSessionState(session.Object); + var state = CreateSession(session.Object); // Act state.Add(key, value); @@ -239,7 +240,7 @@ public void Remove() var key = _fixture.Create(); var session = new Mock(); - var state = new HttpSessionState(session.Object); + var state = CreateSession(session.Object); // Act state.Remove(key); @@ -255,7 +256,7 @@ public void RemoveAll() var key = _fixture.Create(); var session = new Mock(); - var state = new HttpSessionState(session.Object); + var state = CreateSession(session.Object); // Act state.RemoveAll(); @@ -271,7 +272,7 @@ public void Clear() var key = _fixture.Create(); var session = new Mock(); - var state = new HttpSessionState(session.Object); + var state = CreateSession(session.Object); // Act state.Clear(); @@ -289,7 +290,7 @@ public void GetEnumerator() var session = new Mock(); session.Setup(s => s.Keys).Returns(keys); - var state = new HttpSessionState(session.Object); + var state = CreateSession(session.Object); // Act var result = state.GetEnumerator(); @@ -320,7 +321,7 @@ public void CopyTo() session.Setup(s => s[key1]).Returns(item1); session.Setup(s => s[key2]).Returns(item2); - var state = new HttpSessionState(session.Object); + var state = CreateSession(session.Object); var array = new object[3]; // Act @@ -332,4 +333,12 @@ public void CopyTo() item => Assert.Equal(item1, item), item => Assert.Equal(item2, item)); ; } + + private static HttpSessionState CreateSession(ISessionState session) + { + var feature = new Mock(); + feature.Setup(f => f.State).Returns(session); + + return new(feature.Object); + } }