From 321e631bc15185570f9e9e225fbc718de3caeb02 Mon Sep 17 00:00:00 2001
From: Elan Hasson <234704+ElanHasson@users.noreply.github.com>
Date: Thu, 9 May 2024 23:00:56 -0400
Subject: [PATCH 1/2] Scan keyed assemblies as keyed assemblies.
---
src/Oakton/Oakton.csproj | 6 +-
.../Resources/ResourceHostExtensions.cs | 260 +++----
.../Resources/ResourceHostExtensionsTests.cs | 646 +++++++++---------
src/Tests/Tests.csproj | 8 +-
4 files changed, 481 insertions(+), 439 deletions(-)
diff --git a/src/Oakton/Oakton.csproj b/src/Oakton/Oakton.csproj
index 056b41c0..be0087d2 100644
--- a/src/Oakton/Oakton.csproj
+++ b/src/Oakton/Oakton.csproj
@@ -22,7 +22,11 @@
-
+
+
+
+
+
diff --git a/src/Oakton/Resources/ResourceHostExtensions.cs b/src/Oakton/Resources/ResourceHostExtensions.cs
index 0a188cb3..7e70c58c 100644
--- a/src/Oakton/Resources/ResourceHostExtensions.cs
+++ b/src/Oakton/Resources/ResourceHostExtensions.cs
@@ -1,128 +1,134 @@
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Hosting;
-
-namespace Oakton.Resources;
-
-public enum StartupAction
-{
- ///
- /// Only check that each resource is set up and functional
- ///
- SetupOnly,
-
- ///
- /// Check that each resource is set up, functional, and clear off
- /// any existing state. This is mainly meant for automated testing scenarios
- ///
- ResetState
-}
-
-public static class ResourceHostExtensions
-{
- ///
- /// Add a hosted service that will do setup on all registered stateful resources
- ///
- ///
- /// Configure the startup action. The default is SetupOnly
- ///
- public static IServiceCollection AddResourceSetupOnStartup(this IServiceCollection services,
- StartupAction action = StartupAction.SetupOnly)
- {
- if (!services.Any(x =>
- x.ServiceType == typeof(IHostedService) &&
- x.ImplementationType == typeof(ResourceSetupHostService)))
- {
- services.Insert(0,
- new ServiceDescriptor(typeof(IHostedService), typeof(ResourceSetupHostService),
- ServiceLifetime.Singleton));
- services.AddLogging();
- }
-
- var options = new ResourceSetupOptions { Action = action };
- services.AddSingleton(options);
-
- return services;
- }
-
- ///
- /// Add a hosted service that will do setup on all registered stateful resources
- ///
- ///
- /// Configure the startup action. The default is SetupOnly
- ///
- public static IHostBuilder UseResourceSetupOnStartup(this IHostBuilder builder,
- StartupAction action = StartupAction.SetupOnly)
- {
- return builder.ConfigureServices(s => s.AddResourceSetupOnStartup(action));
- }
-
- ///
- /// Add a hosted service that will do setup on all registered stateful resources, but only
- /// if the environment name is "Development"
- ///
- ///
- /// Configure the startup action. The default is SetupOnly
- ///
- public static IHostBuilder UseResourceSetupOnStartupInDevelopment(this IHostBuilder builder,
- StartupAction action = StartupAction.SetupOnly)
- {
- return builder.ConfigureServices((context, services) =>
- {
- if (context.HostingEnvironment.IsDevelopment())
- {
- services.AddResourceSetupOnStartup(action);
- }
- });
- }
-
- ///
- /// Executes SetUp(), then ClearState() on all stateful resources. Useful for automated testing scenarios to
- /// ensure all resources are in a good, known state
- ///
- ///
- ///
- /// Optional filter on resource type name
- /// Optional filter on resource name
- public static async Task ResetResourceState(this IHost host, CancellationToken cancellation = default,
- string resourceType = null, string resourceName = null)
- {
- var resources = ResourcesCommand.FindResources(host.Services, resourceType, resourceName);
- foreach (var resource in resources)
- {
- await resource.Setup(cancellation);
- await resource.ClearState(cancellation);
- }
- }
-
- ///
- /// Executes SetUp() on all stateful resources. Useful for automated testing scenarios to
- /// ensure all resources are in a good, known state
- ///
- ///
- ///
- /// Optional filter on resource type name
- /// Optional filter on resource name
- public static async Task SetupResources(this IHost host, CancellationToken cancellation = default,
- string resourceType = null, string resourceName = null)
- {
- var resources = ResourcesCommand.FindResources(host.Services, resourceType, resourceName);
- foreach (var resource in resources) await resource.Setup(cancellation);
- }
-
- ///
- /// Executes Teardown() on all stateful resources
- ///
- ///
- ///
- /// Optional filter on resource type name
- /// Optional filter on resource name
- public static async Task TeardownResources(this IHost host, CancellationToken cancellation = default,
- string resourceType = null, string resourceName = null)
- {
- var resources = ResourcesCommand.FindResources(host.Services, resourceType, resourceName);
- foreach (var resource in resources) await resource.Teardown(cancellation);
- }
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Oakton.Resources;
+
+public enum StartupAction
+{
+ ///
+ /// Only check that each resource is set up and functional
+ ///
+ SetupOnly,
+
+ ///
+ /// Check that each resource is set up, functional, and clear off
+ /// any existing state. This is mainly meant for automated testing scenarios
+ ///
+ ResetState
+}
+
+public static class ResourceHostExtensions
+{
+ ///
+ /// Add a hosted service that will do setup on all registered stateful resources
+ ///
+ ///
+ /// Configure the startup action. The default is SetupOnly
+ ///
+ public static IServiceCollection AddResourceSetupOnStartup(this IServiceCollection services,
+ StartupAction action = StartupAction.SetupOnly)
+ {
+ if (!services.Any(x =>
+ x.ServiceType == typeof(IHostedService) &&
+#if NET8_0_OR_GREATER
+ x.ServiceKey is not null ?
+ x.KeyedImplementationType == typeof(ResourceSetupHostService) &&
+#else
+ x.ImplementationType == typeof(ResourceSetupHostService)))
+
+#endif
+ {
+ services.Insert(0,
+ new ServiceDescriptor(typeof(IHostedService), typeof(ResourceSetupHostService),
+ ServiceLifetime.Singleton));
+ services.AddLogging();
+ }
+
+ var options = new ResourceSetupOptions { Action = action };
+ services.AddSingleton(options);
+
+ return services;
+ }
+
+ ///
+ /// Add a hosted service that will do setup on all registered stateful resources
+ ///
+ ///
+ /// Configure the startup action. The default is SetupOnly
+ ///
+ public static IHostBuilder UseResourceSetupOnStartup(this IHostBuilder builder,
+ StartupAction action = StartupAction.SetupOnly)
+ {
+ return builder.ConfigureServices(s => s.AddResourceSetupOnStartup(action));
+ }
+
+ ///
+ /// Add a hosted service that will do setup on all registered stateful resources, but only
+ /// if the environment name is "Development"
+ ///
+ ///
+ /// Configure the startup action. The default is SetupOnly
+ ///
+ public static IHostBuilder UseResourceSetupOnStartupInDevelopment(this IHostBuilder builder,
+ StartupAction action = StartupAction.SetupOnly)
+ {
+ return builder.ConfigureServices((context, services) =>
+ {
+ if (context.HostingEnvironment.IsDevelopment())
+ {
+ services.AddResourceSetupOnStartup(action);
+ }
+ });
+ }
+
+ ///
+ /// Executes SetUp(), then ClearState() on all stateful resources. Useful for automated testing scenarios to
+ /// ensure all resources are in a good, known state
+ ///
+ ///
+ ///
+ /// Optional filter on resource type name
+ /// Optional filter on resource name
+ public static async Task ResetResourceState(this IHost host, CancellationToken cancellation = default,
+ string resourceType = null, string resourceName = null)
+ {
+ var resources = ResourcesCommand.FindResources(host.Services, resourceType, resourceName);
+ foreach (var resource in resources)
+ {
+ await resource.Setup(cancellation);
+ await resource.ClearState(cancellation);
+ }
+ }
+
+ ///
+ /// Executes SetUp() on all stateful resources. Useful for automated testing scenarios to
+ /// ensure all resources are in a good, known state
+ ///
+ ///
+ ///
+ /// Optional filter on resource type name
+ /// Optional filter on resource name
+ public static async Task SetupResources(this IHost host, CancellationToken cancellation = default,
+ string resourceType = null, string resourceName = null)
+ {
+ var resources = ResourcesCommand.FindResources(host.Services, resourceType, resourceName);
+ foreach (var resource in resources) await resource.Setup(cancellation);
+ }
+
+ ///
+ /// Executes Teardown() on all stateful resources
+ ///
+ ///
+ ///
+ /// Optional filter on resource type name
+ /// Optional filter on resource name
+ public static async Task TeardownResources(this IHost host, CancellationToken cancellation = default,
+ string resourceType = null, string resourceName = null)
+ {
+ var resources = ResourcesCommand.FindResources(host.Services, resourceType, resourceName);
+ foreach (var resource in resources) await resource.Teardown(cancellation);
+ }
}
\ No newline at end of file
diff --git a/src/Tests/Resources/ResourceHostExtensionsTests.cs b/src/Tests/Resources/ResourceHostExtensionsTests.cs
index 94a6ad9a..41a97197 100644
--- a/src/Tests/Resources/ResourceHostExtensionsTests.cs
+++ b/src/Tests/Resources/ResourceHostExtensionsTests.cs
@@ -1,310 +1,338 @@
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using Lamar;
-using Lamar.Microsoft.DependencyInjection;
-using Microsoft.Extensions.Hosting;
-using NSubstitute;
-using NSubstitute.ReceivedExtensions;
-using Oakton.Resources;
-using Shouldly;
-using Xunit;
-
-namespace Tests.Resources
-{
- public class ResourceHostExtensionsTests : ResourceCommandContext
- {
- public static async Task sample1()
- {
- #region sample_using_AddResourceSetupOnStartup
-
- using var host = await Host.CreateDefaultBuilder()
- .ConfigureServices(services =>
- {
- // More service registrations like this is a real app!
-
- services.AddResourceSetupOnStartup();
- }).StartAsync();
-
- #endregion
- }
-
- public static async Task sample2()
- {
- #region sample_using_AddResourceSetupOnStartup2
-
- using var host = await Host.CreateDefaultBuilder()
- .ConfigureServices(services =>
- {
- // More service registrations like this is a real app!
- })
- .UseResourceSetupOnStartup()
- .StartAsync();
-
- #endregion
- }
-
- public static async Task sample3()
- {
- #region sample_using_AddResourceSetupOnStartup3
-
- using var host = await Host.CreateDefaultBuilder()
- .ConfigureServices(services =>
- {
- // More service registrations like this is a real app!
- })
- .UseResourceSetupOnStartupInDevelopment()
- .StartAsync();
-
- #endregion
- }
-
- #region sample_programmatically_control_resources
-
- public static async Task usages_for_testing(IHost host)
- {
- // Programmatically call Setup() on all resources
- await host.SetupResources();
-
- // Maybe between integration tests, clear any
- // persisted state. For example, I've used this to
- // purge Rabbit MQ queues between tests
- await host.ResetResourceState();
-
- // Tear it all down!
- await host.TeardownResources();
- }
-
- #endregion
-
- [Fact]
- public void add_resource_startup()
- {
- using var container = Container.For(services =>
- {
- services.AddResourceSetupOnStartup();
-
- // Only does it once!
- services.AddResourceSetupOnStartup();
- services.AddResourceSetupOnStartup();
- services.AddResourceSetupOnStartup();
- services.AddResourceSetupOnStartup();
- });
-
- container.Model.For()
- .Instances.Single().ImplementationType.ShouldBe(typeof(ResourceSetupHostService));
-
- container.GetInstance()
- .ShouldBeOfType();
- }
-
- [Fact]
- public void use_resource_setup()
- {
- using var host = Host.CreateDefaultBuilder()
- .UseLamar()
- .UseResourceSetupOnStartup()
- .Build();
-
- var container = (IContainer)host.Services;
-
- container.Model.For()
- .Instances.Single().ImplementationType.ShouldBe(typeof(ResourceSetupHostService));
-
- container.GetInstance()
- .ShouldBeOfType();
- }
-
- [Fact]
- public void use_conditional_resource_setup_in_development()
- {
- using var host = Host.CreateDefaultBuilder()
- .UseLamar()
- .UseResourceSetupOnStartupInDevelopment()
- .UseEnvironment("Development")
- .Build();
-
- var container = (IContainer)host.Services;
-
- container.Model.For()
- .Instances.Single().ImplementationType.ShouldBe(typeof(ResourceSetupHostService));
-
- container.GetInstance()
- .ShouldBeOfType();
- }
-
- [Fact]
- public void use_conditional_resource_setup_only_in_development_does_nothing_in_prod()
- {
- using var host = Host.CreateDefaultBuilder()
- .UseLamar()
- .UseResourceSetupOnStartupInDevelopment()
- .UseEnvironment("Production")
- .Build();
-
- var container = (IContainer)host.Services;
-
- container.Model.For()
- .Instances.Any().ShouldBeFalse();
- }
-
- [Fact]
- public async Task runs_all_resources()
- {
- var blue = AddResource("blue", "color");
- var red = AddResource("red", "color");
-
- AddSource(col =>
- {
- col.Add("purple", "color");
- col.Add("orange", "color");
- });
-
- AddSource(col =>
- {
- col.Add("green", "color");
- col.Add("white", "color");
- });
-
- using var host = await Host.CreateDefaultBuilder()
- .UseResourceSetupOnStartup()
- .ConfigureServices(services =>
- {
- CopyResources(services);
- services.AddResourceSetupOnStartup();
- })
- .StartAsync();
-
- foreach (var resource in AllResources)
- {
- await resource.Received().Setup(Arg.Any());
- await resource.DidNotReceive().ClearState(Arg.Any());
- }
-
- }
-
-
- [Fact]
- public async Task runs_all_resources_and_resets()
- {
- var blue = AddResource("blue", "color");
- var red = AddResource("red", "color");
-
- AddSource(col =>
- {
- col.Add("purple", "color");
- col.Add("orange", "color");
- });
-
- AddSource(col =>
- {
- col.Add("green", "color");
- col.Add("white", "color");
- });
-
- using var host = await Host.CreateDefaultBuilder()
- .UseResourceSetupOnStartup()
- .ConfigureServices(services =>
- {
- CopyResources(services);
- services.AddResourceSetupOnStartup(StartupAction.ResetState);
- })
- .StartAsync();
-
- foreach (var resource in AllResources)
- {
- await resource.Received().Setup(Arg.Any());
- await resource.Received().ClearState(Arg.Any());
- }
-
- }
-
- [Fact]
- public async Task setup_all()
- {
- var blue = AddResource("blue", "color");
- var red = AddResource("red", "color");
-
- AddSource(col =>
- {
- col.Add("purple", "color");
- col.Add("orange", "color");
- });
-
- AddSource(col =>
- {
- col.Add("green", "color");
- col.Add("white", "color");
- });
-
- using var host = await buildHost();
- await host.SetupResources();
-
- foreach (var resource in AllResources)
- {
- await resource.Received().Setup(Arg.Any());
- }
-
-
- }
-
- [Fact]
- public async Task reset_all()
- {
- var blue = AddResource("blue", "color");
- var red = AddResource("red", "color");
-
- AddSource(col =>
- {
- col.Add("purple", "color");
- col.Add("orange", "color");
- });
-
- AddSource(col =>
- {
- col.Add("green", "color");
- col.Add("white", "color");
- });
-
- using var host = await buildHost();
- await host.ResetResourceState();
-
- foreach (var resource in AllResources)
- {
- await resource.Received().Setup(Arg.Any());
- await resource.Received().ClearState(Arg.Any());
- }
-
-
- }
-
- [Fact]
- public async Task teardown_all()
- {
- var blue = AddResource("blue", "color");
- var red = AddResource("red", "color");
-
- AddSource(col =>
- {
- col.Add("purple", "color");
- col.Add("orange", "color");
- });
-
- AddSource(col =>
- {
- col.Add("green", "color");
- col.Add("white", "color");
- });
-
- using var host = await buildHost();
- await host.TeardownResources();
-
- foreach (var resource in AllResources)
- {
- await resource.Received().Teardown(Arg.Any());
- }
-
-
- }
- }
+using Lamar;
+using Lamar.Microsoft.DependencyInjection;
+#if NET8_0_OR_GREATER
+using Microsoft.Extensions.DependencyInjection;
+#endif
+using Microsoft.Extensions.Hosting;
+using NSubstitute;
+using NSubstitute.ReceivedExtensions;
+using Oakton.Resources;
+using Shouldly;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace Tests.Resources
+{
+ public class ResourceHostExtensionsTests : ResourceCommandContext
+ {
+ public static async Task sample1()
+ {
+ #region sample_using_AddResourceSetupOnStartup
+
+ using var host = await Host.CreateDefaultBuilder()
+ .ConfigureServices(services =>
+ {
+ // More service registrations like this is a real app!
+
+ services.AddResourceSetupOnStartup();
+ }).StartAsync();
+
+ #endregion
+ }
+
+ public static async Task sample2()
+ {
+ #region sample_using_AddResourceSetupOnStartup2
+
+ using var host = await Host.CreateDefaultBuilder()
+ .ConfigureServices(services =>
+ {
+ // More service registrations like this is a real app!
+ })
+ .UseResourceSetupOnStartup()
+ .StartAsync();
+
+ #endregion
+ }
+
+ public static async Task sample3()
+ {
+ #region sample_using_AddResourceSetupOnStartup3
+
+ using var host = await Host.CreateDefaultBuilder()
+ .ConfigureServices(services =>
+ {
+ // More service registrations like this is a real app!
+ })
+ .UseResourceSetupOnStartupInDevelopment()
+ .StartAsync();
+
+ #endregion
+ }
+
+ #region sample_programmatically_control_resources
+
+ public static async Task usages_for_testing(IHost host)
+ {
+ // Programmatically call Setup() on all resources
+ await host.SetupResources();
+
+ // Maybe between integration tests, clear any
+ // persisted state. For example, I've used this to
+ // purge Rabbit MQ queues between tests
+ await host.ResetResourceState();
+
+ // Tear it all down!
+ await host.TeardownResources();
+ }
+
+ #endregion
+
+ [Fact]
+ public void add_resource_startup()
+ {
+ using var container = Container.For(services =>
+ {
+ services.AddResourceSetupOnStartup();
+
+ // Only does it once!
+ services.AddResourceSetupOnStartup();
+ services.AddResourceSetupOnStartup();
+ services.AddResourceSetupOnStartup();
+ services.AddResourceSetupOnStartup();
+ });
+
+ container.Model.For()
+ .Instances.Single().ImplementationType.ShouldBe(typeof(ResourceSetupHostService));
+
+ container.GetInstance()
+ .ShouldBeOfType();
+ }
+
+#if NET8_0_OR_GREATER
+ [Fact]
+ public void add_resource_startup_can_handle_keyed_services()
+ {
+ using var container = Container.For(services =>
+ {
+
+ // Add a keyed service.
+ services.AddKeyedSingleton("test", this);
+
+ // This should not throw.
+ services.AddResourceSetupOnStartup();
+
+ // Verify the number of services added by AddTokenAcquisition (ignoring the service we added here).
+ services.Count(t => t.ServiceType != typeof(ResourceHostExtensionsTests)).ShouldBe(10);
+ });
+
+ container.Model.For()
+ .Instances.Single().ImplementationType.ShouldBe(typeof(ResourceSetupHostService));
+
+ container.GetInstance()
+ .ShouldBeOfType();
+ }
+#endif
+
+ [Fact]
+ public void use_resource_setup()
+ {
+ using var host = Host.CreateDefaultBuilder()
+ .UseLamar()
+ .UseResourceSetupOnStartup()
+ .Build();
+
+ var container = (IContainer)host.Services;
+
+ container.Model.For()
+ .Instances.Single().ImplementationType.ShouldBe(typeof(ResourceSetupHostService));
+
+ container.GetInstance()
+ .ShouldBeOfType();
+ }
+
+ [Fact]
+ public void use_conditional_resource_setup_in_development()
+ {
+ using var host = Host.CreateDefaultBuilder()
+ .UseLamar()
+ .UseResourceSetupOnStartupInDevelopment()
+ .UseEnvironment("Development")
+ .Build();
+
+ var container = (IContainer)host.Services;
+
+ container.Model.For()
+ .Instances.Single().ImplementationType.ShouldBe(typeof(ResourceSetupHostService));
+
+ container.GetInstance()
+ .ShouldBeOfType();
+ }
+
+ [Fact]
+ public void use_conditional_resource_setup_only_in_development_does_nothing_in_prod()
+ {
+ using var host = Host.CreateDefaultBuilder()
+ .UseLamar()
+ .UseResourceSetupOnStartupInDevelopment()
+ .UseEnvironment("Production")
+ .Build();
+
+ var container = (IContainer)host.Services;
+
+ container.Model.For()
+ .Instances.Any().ShouldBeFalse();
+ }
+
+ [Fact]
+ public async Task runs_all_resources()
+ {
+ var blue = AddResource("blue", "color");
+ var red = AddResource("red", "color");
+
+ AddSource(col =>
+ {
+ col.Add("purple", "color");
+ col.Add("orange", "color");
+ });
+
+ AddSource(col =>
+ {
+ col.Add("green", "color");
+ col.Add("white", "color");
+ });
+
+ using var host = await Host.CreateDefaultBuilder()
+ .UseResourceSetupOnStartup()
+ .ConfigureServices(services =>
+ {
+ CopyResources(services);
+ services.AddResourceSetupOnStartup();
+ })
+ .StartAsync();
+
+ foreach (var resource in AllResources)
+ {
+ await resource.Received().Setup(Arg.Any());
+ await resource.DidNotReceive().ClearState(Arg.Any());
+ }
+
+ }
+
+
+ [Fact]
+ public async Task runs_all_resources_and_resets()
+ {
+ var blue = AddResource("blue", "color");
+ var red = AddResource("red", "color");
+
+ AddSource(col =>
+ {
+ col.Add("purple", "color");
+ col.Add("orange", "color");
+ });
+
+ AddSource(col =>
+ {
+ col.Add("green", "color");
+ col.Add("white", "color");
+ });
+
+ using var host = await Host.CreateDefaultBuilder()
+ .UseResourceSetupOnStartup()
+ .ConfigureServices(services =>
+ {
+ CopyResources(services);
+ services.AddResourceSetupOnStartup(StartupAction.ResetState);
+ })
+ .StartAsync();
+
+ foreach (var resource in AllResources)
+ {
+ await resource.Received().Setup(Arg.Any());
+ await resource.Received().ClearState(Arg.Any());
+ }
+
+ }
+
+ [Fact]
+ public async Task setup_all()
+ {
+ var blue = AddResource("blue", "color");
+ var red = AddResource("red", "color");
+
+ AddSource(col =>
+ {
+ col.Add("purple", "color");
+ col.Add("orange", "color");
+ });
+
+ AddSource(col =>
+ {
+ col.Add("green", "color");
+ col.Add("white", "color");
+ });
+
+ using var host = await buildHost();
+ await host.SetupResources();
+
+ foreach (var resource in AllResources)
+ {
+ await resource.Received().Setup(Arg.Any());
+ }
+
+
+ }
+
+ [Fact]
+ public async Task reset_all()
+ {
+ var blue = AddResource("blue", "color");
+ var red = AddResource("red", "color");
+
+ AddSource(col =>
+ {
+ col.Add("purple", "color");
+ col.Add("orange", "color");
+ });
+
+ AddSource(col =>
+ {
+ col.Add("green", "color");
+ col.Add("white", "color");
+ });
+
+ using var host = await buildHost();
+ await host.ResetResourceState();
+
+ foreach (var resource in AllResources)
+ {
+ await resource.Received().Setup(Arg.Any());
+ await resource.Received().ClearState(Arg.Any());
+ }
+
+
+ }
+
+ [Fact]
+ public async Task teardown_all()
+ {
+ var blue = AddResource("blue", "color");
+ var red = AddResource("red", "color");
+
+ AddSource(col =>
+ {
+ col.Add("purple", "color");
+ col.Add("orange", "color");
+ });
+
+ AddSource(col =>
+ {
+ col.Add("green", "color");
+ col.Add("white", "color");
+ });
+
+ using var host = await buildHost();
+ await host.TeardownResources();
+
+ foreach (var resource in AllResources)
+ {
+ await resource.Received().Teardown(Arg.Any());
+ }
+
+
+ }
+ }
}
\ No newline at end of file
diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj
index a5243ce6..44552a1a 100644
--- a/src/Tests/Tests.csproj
+++ b/src/Tests/Tests.csproj
@@ -1,4 +1,4 @@
-
+
net6.0;net7.0;net8.0
@@ -22,7 +22,11 @@
-
+
+
+
+
+
From b140580cbdfb17117b30e3d67da994e4bd894688 Mon Sep 17 00:00:00 2001
From: Elan Hasson <234704+ElanHasson@users.noreply.github.com>
Date: Thu, 9 May 2024 23:02:46 -0400
Subject: [PATCH 2/2] fix whitespace
---
src/Oakton/Oakton.csproj | 8 ++++----
src/Oakton/Resources/ResourceHostExtensions.cs | 1 -
src/Tests/Tests.csproj | 8 ++++----
3 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/src/Oakton/Oakton.csproj b/src/Oakton/Oakton.csproj
index be0087d2..9bd25113 100644
--- a/src/Oakton/Oakton.csproj
+++ b/src/Oakton/Oakton.csproj
@@ -22,11 +22,11 @@
-
-
-
+
+
+
-
+
diff --git a/src/Oakton/Resources/ResourceHostExtensions.cs b/src/Oakton/Resources/ResourceHostExtensions.cs
index 7e70c58c..8231862b 100644
--- a/src/Oakton/Resources/ResourceHostExtensions.cs
+++ b/src/Oakton/Resources/ResourceHostExtensions.cs
@@ -38,7 +38,6 @@ x.ServiceKey is not null ?
x.KeyedImplementationType == typeof(ResourceSetupHostService) &&
#else
x.ImplementationType == typeof(ResourceSetupHostService)))
-
#endif
{
services.Insert(0,
diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj
index 44552a1a..e2eff115 100644
--- a/src/Tests/Tests.csproj
+++ b/src/Tests/Tests.csproj
@@ -22,11 +22,11 @@
-
-
-
+
+
+
-
+