diff --git a/Directory.Build.targets b/Directory.Build.targets
index 85731bd..7f3a8bc 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -15,8 +15,8 @@
- 00000
- $(MinVerMajor).$(MinVerMinor).$(MinVerPatch).$(BUILD_BUILDNUMBER)
+ 0
+ $(MinVerMajor).$(MinVerMinor).$(MinVerPatch).$(GITHUB_RUN_NUMBER)
diff --git a/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/Codebelt.Extensions.Xunit.Hosting.AspNetCore.csproj b/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/Codebelt.Extensions.Xunit.Hosting.AspNetCore.csproj
index 0d0173e..0de0868 100644
--- a/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/Codebelt.Extensions.Xunit.Hosting.AspNetCore.csproj
+++ b/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/Codebelt.Extensions.Xunit.Hosting.AspNetCore.csproj
@@ -24,8 +24,7 @@
-
-
+
diff --git a/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/Http/FakeHttpContextAccessor.cs b/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/Http/FakeHttpContextAccessor.cs
index 1346dc5..65437f6 100644
--- a/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/Http/FakeHttpContextAccessor.cs
+++ b/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/Http/FakeHttpContextAccessor.cs
@@ -1,5 +1,8 @@
-using Codebelt.Extensions.Xunit.Hosting.AspNetCore.Http.Features;
-using Cuemon.IO;
+using System;
+using System.IO;
+using System.Text;
+using Codebelt.Extensions.Xunit.Hosting.AspNetCore.Http.Features;
+using Cuemon;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
@@ -20,10 +23,23 @@ public FakeHttpContextAccessor()
var fc = new FeatureCollection();
fc.Set(new FakeHttpResponseFeature());
fc.Set(new FakeHttpRequestFeature());
- fc.Set(new StreamResponseBodyFeature(StreamFactory.Create(writer => writer.Write("Hello awesome developers!"))));
+ fc.Set(new StreamResponseBodyFeature(MakeGreeting("Hello awesome developers!")));
HttpContext = new DefaultHttpContext(fc);
}
+ private Stream MakeGreeting(string greeting)
+ {
+ return Patterns.SafeInvoke(() => new MemoryStream(), ms =>
+ {
+ var sw = new StreamWriter(ms, Encoding.UTF8);
+ sw.Write(greeting);
+ sw.Flush();
+ ms.Flush();
+ ms.Position = 0;
+ return ms;
+ }, ex => throw new InvalidOperationException("There is an error in the Stream being written.", ex));
+ }
+
///
/// Gets or sets the HTTP context.
///
diff --git a/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/ServiceCollectionExtensions.cs b/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/ServiceCollectionExtensions.cs
index ced4ae9..859d0d3 100644
--- a/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/ServiceCollectionExtensions.cs
+++ b/src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/ServiceCollectionExtensions.cs
@@ -1,7 +1,9 @@
-using Codebelt.Extensions.Xunit.Hosting.AspNetCore.Http;
-using Cuemon.Extensions.DependencyInjection;
+using System;
+using System.ComponentModel;
+using Codebelt.Extensions.Xunit.Hosting.AspNetCore.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
namespace Codebelt.Extensions.Xunit.Hosting.AspNetCore
{
@@ -18,18 +20,27 @@ public static class ServiceCollectionExtensions
/// A reference to after the operation has completed.
public static IServiceCollection AddFakeHttpContextAccessor(this IServiceCollection services, ServiceLifetime lifetime)
{
- services.TryAdd(provider =>
+ switch (lifetime)
{
- var contextAccessor = new FakeHttpContextAccessor
- {
- HttpContext =
- {
- RequestServices = provider
- }
- };
- return contextAccessor;
- }, lifetime);
+ case ServiceLifetime.Transient:
+ services.TryAddTransient(FakeHttpContextAccessorFactory);
+ break;
+ case ServiceLifetime.Scoped:
+ services.TryAddScoped(FakeHttpContextAccessorFactory);
+ break;
+ case ServiceLifetime.Singleton:
+ services.TryAddSingleton(FakeHttpContextAccessorFactory);
+ break;
+ default:
+ throw new InvalidEnumArgumentException(nameof(lifetime), (int)lifetime, typeof(ServiceLifetime));
+ }
return services;
}
+
+ private static IHttpContextAccessor FakeHttpContextAccessorFactory(IServiceProvider provider)
+ {
+ var contextAccessor = new FakeHttpContextAccessor { HttpContext = { RequestServices = provider } };
+ return contextAccessor;
+ }
}
}
diff --git a/src/Codebelt.Extensions.Xunit.Hosting/Codebelt.Extensions.Xunit.Hosting.csproj b/src/Codebelt.Extensions.Xunit.Hosting/Codebelt.Extensions.Xunit.Hosting.csproj
index d8b4cf5..2fb51d3 100644
--- a/src/Codebelt.Extensions.Xunit.Hosting/Codebelt.Extensions.Xunit.Hosting.csproj
+++ b/src/Codebelt.Extensions.Xunit.Hosting/Codebelt.Extensions.Xunit.Hosting.csproj
@@ -35,6 +35,7 @@
+
diff --git a/src/Codebelt.Extensions.Xunit.Hosting/GlobalSuppressions.cs b/src/Codebelt.Extensions.Xunit.Hosting/GlobalSuppressions.cs
new file mode 100644
index 0000000..b73414a
--- /dev/null
+++ b/src/Codebelt.Extensions.Xunit.Hosting/GlobalSuppressions.cs
@@ -0,0 +1,8 @@
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project.
+// Project-level suppressions either have no target or are given
+// a specific target and scoped to a namespace, type, member, etc.
+
+using System.Diagnostics.CodeAnalysis;
+
+[assembly: SuppressMessage("Major Code Smell", "S3881:\"IDisposable\" should be implemented correctly", Justification = "This is an implementation of the IDisposable interface tailored to avoid wrong implementations.", Scope = "type", Target = "~T:Codebelt.Extensions.Xunit.Hosting.HostFixture")]
diff --git a/src/Codebelt.Extensions.Xunit.Hosting/HostFixture.cs b/src/Codebelt.Extensions.Xunit.Hosting/HostFixture.cs
index efba269..572fdac 100644
--- a/src/Codebelt.Extensions.Xunit.Hosting/HostFixture.cs
+++ b/src/Codebelt.Extensions.Xunit.Hosting/HostFixture.cs
@@ -11,9 +11,8 @@ namespace Codebelt.Extensions.Xunit.Hosting
///
/// Provides a default implementation of the interface.
///
- ///
///
- public class HostFixture : Disposable, IHostFixture
+ public class HostFixture : IDisposable, IHostFixture
{
///
/// Initializes a new instance of the class.
@@ -127,9 +126,15 @@ public virtual void ConfigureHost(Test hostTest)
#endif
///
- /// Called when this object is being disposed by either or having disposing set to true and is false.
+ /// Gets a value indicating whether this object is disposed.
///
- protected override void OnDisposeManagedResources()
+ /// true if this object is disposed; otherwise, false.
+ public bool Disposed { get; private set; }
+
+ ///
+ /// Called when this object is being disposed by either or having disposing set to true and is false.
+ ///
+ protected virtual void OnDisposeManagedResources()
{
if (ServiceProvider is ServiceProvider sp)
{
@@ -137,5 +142,36 @@ protected override void OnDisposeManagedResources()
}
Host?.Dispose();
}
+
+ ///
+ /// Called when this object is being disposed by either or and is false.
+ ///
+ protected virtual void OnDisposeUnmanagedResources()
+ {
+ }
+
+ ///
+ /// Releases all resources used by the object.
+ ///
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ ///
+ /// Releases the unmanaged resources used by the object and optionally releases the managed resources.
+ ///
+ /// true to release both managed and unmanaged resources; false to release only unmanaged resources.
+ protected void Dispose(bool disposing)
+ {
+ if (Disposed) { return; }
+ if (disposing)
+ {
+ OnDisposeManagedResources();
+ }
+ OnDisposeUnmanagedResources();
+ Disposed = true;
+ }
}
}
diff --git a/src/Codebelt.Extensions.Xunit/Codebelt.Extensions.Xunit.csproj b/src/Codebelt.Extensions.Xunit/Codebelt.Extensions.Xunit.csproj
index f09b8d9..24867e4 100644
--- a/src/Codebelt.Extensions.Xunit/Codebelt.Extensions.Xunit.csproj
+++ b/src/Codebelt.Extensions.Xunit/Codebelt.Extensions.Xunit.csproj
@@ -2,6 +2,7 @@
0d0bdf91-e7c7-4cb4-a39d-e1a5374c5602
+ true
@@ -10,7 +11,7 @@
-
+
diff --git a/src/Codebelt.Extensions.Xunit/Test.cs b/src/Codebelt.Extensions.Xunit/Test.cs
index 02172cb..d3ed751 100644
--- a/src/Codebelt.Extensions.Xunit/Test.cs
+++ b/src/Codebelt.Extensions.Xunit/Test.cs
@@ -66,7 +66,7 @@ protected Test(ITestOutputHelper output = null, Type callerType = null)
///
/// Gets a value indicating whether has a reference to an implementation of .
///
- /// true if this instance has has a reference to an implementation of ; otherwise, false.
+ /// true if this instance has a reference to an implementation of ; otherwise, false.
protected bool HasTestOutput => TestOutput != null;
///
diff --git a/test/Codebelt.Extensions.Xunit.Hosting.AspNetCore.Tests/Codebelt.Extensions.Xunit.Hosting.AspNetCore.Tests.csproj b/test/Codebelt.Extensions.Xunit.Hosting.AspNetCore.Tests/Codebelt.Extensions.Xunit.Hosting.AspNetCore.Tests.csproj
index f87662d..c67c1ea 100644
--- a/test/Codebelt.Extensions.Xunit.Hosting.AspNetCore.Tests/Codebelt.Extensions.Xunit.Hosting.AspNetCore.Tests.csproj
+++ b/test/Codebelt.Extensions.Xunit.Hosting.AspNetCore.Tests/Codebelt.Extensions.Xunit.Hosting.AspNetCore.Tests.csproj
@@ -6,7 +6,6 @@
-
diff --git a/test/Codebelt.Extensions.Xunit.Hosting.AspNetCore.Tests/ServiceCollectionExtensionsTest.cs b/test/Codebelt.Extensions.Xunit.Hosting.AspNetCore.Tests/ServiceCollectionExtensionsTest.cs
new file mode 100644
index 0000000..dfb1996
--- /dev/null
+++ b/test/Codebelt.Extensions.Xunit.Hosting.AspNetCore.Tests/ServiceCollectionExtensionsTest.cs
@@ -0,0 +1,46 @@
+using System.ComponentModel;
+using Codebelt.Extensions.Xunit.Hosting.AspNetCore.Http;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.DependencyInjection;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Codebelt.Extensions.Xunit.Hosting.AspNetCore
+{
+ public class ServiceCollectionExtensionsTest : Test
+ {
+ public ServiceCollectionExtensionsTest(ITestOutputHelper output) : base(output)
+ {
+ }
+
+ [Theory]
+ [InlineData(ServiceLifetime.Transient)]
+ [InlineData(ServiceLifetime.Scoped)]
+ [InlineData(ServiceLifetime.Singleton)]
+ public void AddFakeHttpContextAccessor_ShouldAddService(ServiceLifetime lifetime)
+ {
+ // Arrange
+ var services = new ServiceCollection();
+
+ // Act
+ services.AddFakeHttpContextAccessor(lifetime);
+ var serviceProvider = services.BuildServiceProvider();
+ var httpContextAccessor = serviceProvider.GetService();
+
+ // Assert
+ Assert.NotNull(httpContextAccessor);
+ Assert.IsType(httpContextAccessor);
+ }
+
+ [Fact]
+ public void AddFakeHttpContextAccessor_ShouldThrowInvalidEnumArgumentException_ForInvalidLifetime()
+ {
+ // Arrange
+ var services = new ServiceCollection();
+ var invalidLifetime = (ServiceLifetime)999;
+
+ // Act & Assert
+ Assert.Throws(() => services.AddFakeHttpContextAccessor(invalidLifetime));
+ }
+ }
+}
diff --git a/test/Codebelt.Extensions.Xunit.Hosting.Tests/Codebelt.Extensions.Xunit.Hosting.Tests.csproj b/test/Codebelt.Extensions.Xunit.Hosting.Tests/Codebelt.Extensions.Xunit.Hosting.Tests.csproj
index 7fa1000..cae2ea1 100644
--- a/test/Codebelt.Extensions.Xunit.Hosting.Tests/Codebelt.Extensions.Xunit.Hosting.Tests.csproj
+++ b/test/Codebelt.Extensions.Xunit.Hosting.Tests/Codebelt.Extensions.Xunit.Hosting.Tests.csproj
@@ -15,6 +15,7 @@
+
diff --git a/test/Codebelt.Extensions.Xunit.Tests/Assets/UnmanagedDisposable.cs b/test/Codebelt.Extensions.Xunit.Tests/Assets/UnmanagedDisposable.cs
index fb07024..19da2fc 100644
--- a/test/Codebelt.Extensions.Xunit.Tests/Assets/UnmanagedDisposable.cs
+++ b/test/Codebelt.Extensions.Xunit.Tests/Assets/UnmanagedDisposable.cs
@@ -82,7 +82,6 @@ public UnmanagedDisposable()
Dispose(false);
}
-
protected override void OnDisposeManagedResources()
{