diff --git a/src/ClearHostedEndpoint.SqlServerTransport/Examples.cs b/src/ClearHostedEndpoint.SqlServerTransport/Examples.cs index dc36774..aa90a2b 100644 --- a/src/ClearHostedEndpoint.SqlServerTransport/Examples.cs +++ b/src/ClearHostedEndpoint.SqlServerTransport/Examples.cs @@ -1,14 +1,18 @@ -using ClearMeasure.HostedEndpoint; -using ClearMeasure.HostedEndpoint.SqlServerTransport; -using NServiceBus; - -namespace YourNamespace; - -/// -/// Example of a simple NServiceBus endpoint using SQL Server transport. -/// -public class SimpleEndpoint : ClearHostedEndpoint -{ +using ClearMeasure.HostedEndpoint; +using ClearMeasure.HostedEndpoint.SqlServerTransport; +using Microsoft.Extensions.Configuration; +using NServiceBus; + +namespace YourNamespace; + +/// +/// Example of a simple NServiceBus endpoint using SQL Server transport. +/// +public class SimpleEndpoint : ClearHostedEndpoint +{ + public SimpleEndpoint(IConfiguration configuration) : base(configuration) + { + } protected override void ConfigureTransport(EndpointConfiguration endpointConfiguration) { // Single line configuration with SQL Server transport @@ -16,11 +20,14 @@ protected override void ConfigureTransport(EndpointConfiguration endpointConfigu } } -/// -/// Example with custom transport options. -/// -public class CustomEndpoint : ClearHostedEndpoint -{ +/// +/// Example with custom transport options. +/// +public class CustomEndpoint : ClearHostedEndpoint +{ + public CustomEndpoint(IConfiguration configuration) : base(configuration) + { + } protected override void ConfigureTransport(EndpointConfiguration endpointConfiguration) { var options = new SqlServerTransportOptions diff --git a/src/ClearHostedEndpoint.Tests/ClearHostedEndpointTests.cs b/src/ClearHostedEndpoint.Tests/ClearHostedEndpointTests.cs index 19621a3..7bbdb6a 100644 --- a/src/ClearHostedEndpoint.Tests/ClearHostedEndpointTests.cs +++ b/src/ClearHostedEndpoint.Tests/ClearHostedEndpointTests.cs @@ -11,7 +11,7 @@ public class ClearHostedEndpointTests public async Task StartAsync_WithLearningTransport_ShouldStartSuccessfully() { // Arrange - var endpoint = new TestEndpoint(); + var endpoint = new TestEndpoint(TestHelpers.CreateTestConfiguration()); try { @@ -39,7 +39,7 @@ public async Task StartAsync_WithLearningTransport_ShouldStartSuccessfully() public async Task StartAsync_ShouldCallLifecycleMethods_InCorrectOrder() { // Arrange - var endpoint = new TestEndpoint(); + var endpoint = new TestEndpoint(TestHelpers.CreateTestConfiguration()); var callOrder = new List(); try @@ -64,7 +64,7 @@ public async Task StartAsync_ShouldCallLifecycleMethods_InCorrectOrder() public async Task EndpointInstance_BeforeStart_ShouldThrowInvalidOperationException() { // Arrange - var endpoint = new TestEndpoint(); + var endpoint = new TestEndpoint(TestHelpers.CreateTestConfiguration()); // Act & Assert var act = () => @@ -84,7 +84,7 @@ public async Task EndpointInstance_BeforeStart_ShouldThrowInvalidOperationExcept public async Task StopAsync_ShouldStopEndpoint_Gracefully() { // Arrange - var endpoint = new TestEndpoint(); + var endpoint = new TestEndpoint(TestHelpers.CreateTestConfiguration()); try { @@ -106,7 +106,7 @@ public async Task StopAsync_ShouldStopEndpoint_Gracefully() public void EffectiveEndpointName_WithNoCustomName_ShouldUseTypeName() { // Arrange - var endpoint = new TestEndpoint(); + var endpoint = new TestEndpoint(TestHelpers.CreateTestConfiguration()); // Act var effectiveName = endpoint.GetType() @@ -124,7 +124,7 @@ public void EffectiveEndpointName_WithCustomName_ShouldUseCustomName() { // Arrange var customName = "MyCustomEndpoint"; - var endpoint = new CustomNamedEndpoint(customName); + var endpoint = new CustomNamedEndpoint(TestHelpers.CreateTestConfiguration(), customName); // Act var effectiveName = endpoint.GetType() @@ -141,7 +141,7 @@ public void EffectiveEndpointName_WithCustomName_ShouldUseCustomName() public async Task StartAsync_WithFaultyTransport_ShouldThrowEndpointConfigurationException() { // Arrange - var endpoint = new FaultyTransportEndpoint(); + var endpoint = new FaultyTransportEndpoint(TestHelpers.CreateTestConfiguration()); // Act var act = async () => await endpoint.StartAsync(CancellationToken.None); @@ -157,7 +157,7 @@ await act.Should().ThrowAsync() public async Task ExecuteAsync_ShouldKeepServiceAlive_UntilCancellationRequested() { // Arrange - var endpoint = new TestEndpoint(); + var endpoint = new TestEndpoint(TestHelpers.CreateTestConfiguration()); var cts = new CancellationTokenSource(); try @@ -184,7 +184,7 @@ public async Task ExecuteAsync_ShouldKeepServiceAlive_UntilCancellationRequested public void Dispose_ShouldCleanupResources() { // Arrange - var endpoint = new TestEndpoint(); + var endpoint = new TestEndpoint(TestHelpers.CreateTestConfiguration()); // Act endpoint.Dispose(); @@ -196,7 +196,7 @@ public void Dispose_ShouldCleanupResources() public void Dispose_CalledMultipleTimes_ShouldNotThrow() { // Arrange - var endpoint = new TestEndpoint(); + var endpoint = new TestEndpoint(TestHelpers.CreateTestConfiguration()); // Act endpoint.Dispose(); diff --git a/src/ClearHostedEndpoint.Tests/CustomConfigurationTests.cs b/src/ClearHostedEndpoint.Tests/CustomConfigurationTests.cs index 000eac4..f0ecb9a 100644 --- a/src/ClearHostedEndpoint.Tests/CustomConfigurationTests.cs +++ b/src/ClearHostedEndpoint.Tests/CustomConfigurationTests.cs @@ -9,7 +9,7 @@ public class CustomConfigurationTests public async Task CustomRecoverabilityEndpoint_ShouldUseCustomRetrySettings() { // Arrange - var endpoint = new CustomRecoverabilityEndpoint + var endpoint = new CustomRecoverabilityEndpoint(TestHelpers.CreateTestConfiguration()) { CustomImmediateRetries = 5, CustomDelayedRetries = 10 @@ -35,7 +35,7 @@ public async Task CustomNamedEndpoint_ShouldUseProvidedName() { // Arrange var customName = "MyCustomEndpoint"; - var endpoint = new CustomNamedEndpoint(customName); + var endpoint = new CustomNamedEndpoint(TestHelpers.CreateTestConfiguration(), customName); try { @@ -66,7 +66,7 @@ public void CreateDbConnection_ShouldCreateValidConnection() { ConnectionString = "Server=localhost;Database=Test;" }; - var endpoint = new SqlPersistenceEndpoint(sqlOptions); + var endpoint = new SqlPersistenceEndpoint(TestHelpers.CreateTestConfiguration(), sqlOptions); var connectionString = "Server=localhost;Database=Test;"; // Act @@ -86,7 +86,7 @@ public void CreateDbConnection_ShouldCreateValidConnection() public async Task Endpoint_WithCustomSerialization_CanOverrideDefault() { // Arrange - var endpoint = new TestEndpoint(); + var endpoint = new TestEndpoint(TestHelpers.CreateTestConfiguration()); try { @@ -108,7 +108,7 @@ public async Task Endpoint_WithCustomSerialization_CanOverrideDefault() public async Task Endpoint_ConfigureEndpointAsync_AllowsAsyncConfiguration() { // Arrange - var endpoint = new TestEndpoint(); + var endpoint = new TestEndpoint(TestHelpers.CreateTestConfiguration()); try { @@ -134,7 +134,7 @@ public async Task Endpoint_ConfigureEndpointAsync_AllowsAsyncConfiguration() public async Task Endpoint_WithVariousNames_ShouldHandleCorrectly(string endpointName) { // Arrange - var endpoint = new CustomNamedEndpoint(endpointName); + var endpoint = new CustomNamedEndpoint(TestHelpers.CreateTestConfiguration(), endpointName); try { @@ -170,7 +170,7 @@ public async Task Endpoint_WithComplexConfiguration_ShouldHandleAllSettings() EnableOutbox = false }; - var endpoint = new TestEndpoint(endpointOptions: endpointOptions); + var endpoint = new TestEndpoint(TestHelpers.CreateTestConfiguration(), endpointOptions: endpointOptions); try { diff --git a/src/ClearHostedEndpoint.Tests/DependencyInjectionTests.cs b/src/ClearHostedEndpoint.Tests/DependencyInjectionTests.cs index 31db3d4..87039ae 100644 --- a/src/ClearHostedEndpoint.Tests/DependencyInjectionTests.cs +++ b/src/ClearHostedEndpoint.Tests/DependencyInjectionTests.cs @@ -11,7 +11,7 @@ public class DependencyInjectionTests public async Task Endpoint_WithRegisteredDependencies_ShouldResolveServices() { // Arrange - var endpoint = new DependencyInjectionEndpoint(); + var endpoint = new DependencyInjectionEndpoint(TestHelpers.CreateTestConfiguration()); try { @@ -32,8 +32,8 @@ public async Task Endpoint_WithRegisteredDependencies_ShouldResolveServices() public async Task Endpoint_ShouldHaveIsolatedServiceProvider() { // Arrange - var endpoint1 = new DependencyInjectionEndpoint(); - var endpoint2 = new DependencyInjectionEndpoint(); + var endpoint1 = new DependencyInjectionEndpoint(TestHelpers.CreateTestConfiguration()); + var endpoint2 = new DependencyInjectionEndpoint(TestHelpers.CreateTestConfiguration()); try { @@ -57,7 +57,7 @@ public async Task Endpoint_ShouldHaveIsolatedServiceProvider() public async Task RegisterDependencyInjection_ShouldBeCalledDuringStartup() { // Arrange - var endpoint = new DependencyInjectionEndpoint(); + var endpoint = new DependencyInjectionEndpoint(TestHelpers.CreateTestConfiguration()); try { @@ -78,7 +78,7 @@ public async Task RegisterDependencyInjection_ShouldBeCalledDuringStartup() public void CreateServiceCollection_ShouldReturnNewServiceCollection() { // Arrange - var endpoint = new TestEndpoint(); + var endpoint = new TestEndpoint(TestHelpers.CreateTestConfiguration()); // Act var method = endpoint.GetType() diff --git a/src/ClearHostedEndpoint.Tests/EndpointIntegrationTests.cs b/src/ClearHostedEndpoint.Tests/EndpointIntegrationTests.cs index 3aaca06..73b96cb 100644 --- a/src/ClearHostedEndpoint.Tests/EndpointIntegrationTests.cs +++ b/src/ClearHostedEndpoint.Tests/EndpointIntegrationTests.cs @@ -9,7 +9,7 @@ public class EndpointIntegrationTests public async Task FullLifecycle_StartWorkStop_ShouldCompleteSuccessfully() { // Arrange - var endpoint = new TestEndpoint(); + var endpoint = new TestEndpoint(TestHelpers.CreateTestConfiguration()); try { @@ -36,10 +36,12 @@ public async Task MultipleEndpoints_WithDifferentConfigurations_ShouldRunIndepen { // Arrange var endpoint1 = new TestEndpoint( + TestHelpers.CreateTestConfiguration(), endpointOptions: new EndpointOptions { EndpointName = "Endpoint1" }); var endpoint2 = new TestEndpoint( + TestHelpers.CreateTestConfiguration(), endpointOptions: new EndpointOptions { EndpointName = "Endpoint2", MaxConcurrency = 5 }); - var endpoint3 = new CustomNamedEndpoint("Endpoint3"); + var endpoint3 = new CustomNamedEndpoint(TestHelpers.CreateTestConfiguration(), "Endpoint3"); try { @@ -70,7 +72,7 @@ public async Task MultipleEndpoints_WithDifferentConfigurations_ShouldRunIndepen public async Task Endpoint_WithLongRunningWork_ShouldCancelGracefully() { // Arrange - var endpoint = new TestEndpoint(); + var endpoint = new TestEndpoint(TestHelpers.CreateTestConfiguration()); var cts = new CancellationTokenSource(); try @@ -106,8 +108,8 @@ public async Task Endpoint_WithAllFeatures_ShouldStartAndStopSuccessfully() DelayedRetryCount = 2 }; - var endpoint = new DependencyInjectionEndpoint(); - var customEndpointWithOptions = new TestEndpoint(endpointOptions: endpointOptions); + var endpoint = new DependencyInjectionEndpoint(TestHelpers.CreateTestConfiguration()); + var customEndpointWithOptions = new TestEndpoint(TestHelpers.CreateTestConfiguration(), endpointOptions: endpointOptions); try { @@ -163,7 +165,7 @@ public async Task Endpoint_RestartAfterStop_ShouldWorkCorrectly() public async Task Endpoint_WithCustomRecoverability_ShouldApplySettings() { // Arrange - var endpoint = new CustomRecoverabilityEndpoint + var endpoint = new CustomRecoverabilityEndpoint(TestHelpers.CreateTestConfiguration()) { CustomImmediateRetries = 7, CustomDelayedRetries = 3 @@ -188,7 +190,7 @@ public async Task Endpoint_WithCustomRecoverability_ShouldApplySettings() public async Task Endpoint_WithCancellationDuringStartup_ShouldHandleGracefully() { // Arrange - var endpoint = new TestEndpoint(); + var endpoint = new TestEndpoint(TestHelpers.CreateTestConfiguration()); var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(100)); try diff --git a/src/ClearHostedEndpoint.Tests/EndpointLifecycleTests.cs b/src/ClearHostedEndpoint.Tests/EndpointLifecycleTests.cs index 78cd7dc..1ceb010 100644 --- a/src/ClearHostedEndpoint.Tests/EndpointLifecycleTests.cs +++ b/src/ClearHostedEndpoint.Tests/EndpointLifecycleTests.cs @@ -9,7 +9,7 @@ public class EndpointLifecycleTests public async Task StartAsync_ThenStopAsync_ShouldCompleteSuccessfully() { // Arrange - var endpoint = new TestEndpoint(); + var endpoint = new TestEndpoint(TestHelpers.CreateTestConfiguration()); // Act & Assert await endpoint.StartAsync(CancellationToken.None); @@ -23,7 +23,7 @@ public async Task StartAsync_ThenStopAsync_ShouldCompleteSuccessfully() public async Task OnStoppingAsync_ShouldBeCalledDuringShutdown() { // Arrange - var endpoint = new TestEndpoint(); + var endpoint = new TestEndpoint(TestHelpers.CreateTestConfiguration()); try { @@ -47,7 +47,7 @@ public async Task OnStoppingAsync_ShouldBeCalledDuringShutdown() public async Task StopAsync_WithCancellationToken_ShouldRespectCancellation() { // Arrange - var endpoint = new TestEndpoint(); + var endpoint = new TestEndpoint(TestHelpers.CreateTestConfiguration()); var cts = new CancellationTokenSource(); try @@ -71,7 +71,7 @@ public async Task StopAsync_WithCancellationToken_ShouldRespectCancellation() public async Task Dispose_AfterStop_ShouldNotThrow() { // Arrange - var endpoint = new TestEndpoint(); + var endpoint = new TestEndpoint(TestHelpers.CreateTestConfiguration()); await endpoint.StartAsync(CancellationToken.None); await Task.Delay(500); @@ -87,7 +87,7 @@ public async Task Dispose_AfterStop_ShouldNotThrow() public async Task Dispose_WithoutStop_ShouldNotThrow() { // Arrange - var endpoint = new TestEndpoint(); + var endpoint = new TestEndpoint(TestHelpers.CreateTestConfiguration()); await endpoint.StartAsync(CancellationToken.None); await Task.Delay(500); @@ -102,7 +102,7 @@ public async Task Dispose_WithoutStop_ShouldNotThrow() public void Dispose_WithoutStart_ShouldNotThrow() { // Arrange - var endpoint = new TestEndpoint(); + var endpoint = new TestEndpoint(TestHelpers.CreateTestConfiguration()); // Act endpoint.Dispose(); @@ -114,9 +114,9 @@ public void Dispose_WithoutStart_ShouldNotThrow() public async Task MultipleEndpoints_CanRunConcurrently() { // Arrange - var endpoint1 = new TestEndpoint(); - var endpoint2 = new TestEndpoint(); - var endpoint3 = new TestEndpoint(); + var endpoint1 = new TestEndpoint(TestHelpers.CreateTestConfiguration()); + var endpoint2 = new TestEndpoint(TestHelpers.CreateTestConfiguration()); + var endpoint3 = new TestEndpoint(TestHelpers.CreateTestConfiguration()); try { diff --git a/src/ClearHostedEndpoint.Tests/ErrorHandlingTests.cs b/src/ClearHostedEndpoint.Tests/ErrorHandlingTests.cs index b4f129a..d27d3b4 100644 --- a/src/ClearHostedEndpoint.Tests/ErrorHandlingTests.cs +++ b/src/ClearHostedEndpoint.Tests/ErrorHandlingTests.cs @@ -9,7 +9,7 @@ public class ErrorHandlingTests public async Task Endpoint_WithInvalidTransportConfiguration_ShouldThrowEndpointConfigurationException() { // Arrange - var endpoint = new FaultyTransportEndpoint(); + var endpoint = new FaultyTransportEndpoint(TestHelpers.CreateTestConfiguration()); // Act var act = async () => await endpoint.StartAsync(CancellationToken.None); @@ -29,7 +29,7 @@ public async Task Endpoint_WithNullSqlConnectionString_ShouldThrowEndpointConfig { ConnectionString = null }; - var endpoint = new SqlPersistenceEndpoint(sqlOptions); + var endpoint = new SqlPersistenceEndpoint(TestHelpers.CreateTestConfiguration(), sqlOptions); // Act var act = async () => await endpoint.StartAsync(CancellationToken.None); @@ -50,7 +50,7 @@ public async Task Endpoint_WithEmptySqlConnectionString_ShouldThrowEndpointConfi { ConnectionString = string.Empty }; - var endpoint = new SqlPersistenceEndpoint(sqlOptions); + var endpoint = new SqlPersistenceEndpoint(TestHelpers.CreateTestConfiguration(), sqlOptions); // Act var act = async () => await endpoint.StartAsync(CancellationToken.None); @@ -67,7 +67,7 @@ await act.Should().ThrowAsync() public void Dispose_CalledMultipleTimes_ShouldHandleGracefully() { // Arrange - var endpoint = new TestEndpoint(); + var endpoint = new TestEndpoint(TestHelpers.CreateTestConfiguration()); // Act & Assert endpoint.Dispose(); @@ -79,7 +79,7 @@ public void Dispose_CalledMultipleTimes_ShouldHandleGracefully() public async Task StopAsync_BeforeStartAsync_ShouldHandleGracefully() { // Arrange - var endpoint = new TestEndpoint(); + var endpoint = new TestEndpoint(TestHelpers.CreateTestConfiguration()); try { @@ -98,7 +98,7 @@ public async Task StopAsync_BeforeStartAsync_ShouldHandleGracefully() public async Task StopAsync_WithVeryShortTimeout_ShouldAttemptGracefulShutdown() { // Arrange - var endpoint = new TestEndpoint(); + var endpoint = new TestEndpoint(TestHelpers.CreateTestConfiguration()); var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(1)); try diff --git a/src/ClearHostedEndpoint.Tests/GlobalUsings.cs b/src/ClearHostedEndpoint.Tests/GlobalUsings.cs index 018d802..dcfee8a 100644 --- a/src/ClearHostedEndpoint.Tests/GlobalUsings.cs +++ b/src/ClearHostedEndpoint.Tests/GlobalUsings.cs @@ -1,6 +1,7 @@ -global using Xunit; -global using FluentAssertions; -global using Moq; -global using ClearMeasure.HostedEndpoint; -global using ClearMeasure.HostedEndpoint.Configuration; -global using ClearMeasure.HostedEndpoint.Exceptions; +global using Xunit; +global using FluentAssertions; +global using Moq; +global using ClearMeasure.HostedEndpoint; +global using ClearMeasure.HostedEndpoint.Configuration; +global using ClearMeasure.HostedEndpoint.Exceptions; +global using Microsoft.Extensions.Configuration; diff --git a/src/ClearHostedEndpoint.Tests/SqlPersistenceConfigurationTests.cs b/src/ClearHostedEndpoint.Tests/SqlPersistenceConfigurationTests.cs index 72ec607..1fb4a39 100644 --- a/src/ClearHostedEndpoint.Tests/SqlPersistenceConfigurationTests.cs +++ b/src/ClearHostedEndpoint.Tests/SqlPersistenceConfigurationTests.cs @@ -9,7 +9,7 @@ public class SqlPersistenceConfigurationTests public async Task Endpoint_WithoutSqlPersistence_ShouldUseLearningPersistence() { // Arrange - var endpoint = new TestEndpoint(); + var endpoint = new TestEndpoint(TestHelpers.CreateTestConfiguration()); try { @@ -36,7 +36,7 @@ public async Task Endpoint_WithSqlPersistence_ShouldConfigureSqlPersistence() ConnectionString = "Server=localhost;Database=TestDb;Trusted_Connection=true;", Schema = "dbo" }; - var endpoint = new SqlPersistenceEndpoint(sqlOptions); + var endpoint = new SqlPersistenceEndpoint(TestHelpers.CreateTestConfiguration(), sqlOptions); try { @@ -62,7 +62,7 @@ public async Task Endpoint_WithSqlPersistence_AndCustomSchema_ShouldUseCustomSch ConnectionString = "Server=localhost;Database=TestDb;Trusted_Connection=true;", Schema = "messaging" }; - var endpoint = new SqlPersistenceEndpoint(sqlOptions); + var endpoint = new SqlPersistenceEndpoint(TestHelpers.CreateTestConfiguration(), sqlOptions); try { @@ -88,7 +88,7 @@ public async Task Endpoint_WithSqlPersistence_AndCustomTablePrefix_ShouldUseCust ConnectionString = "Server=localhost;Database=TestDb;Trusted_Connection=true;", TablePrefix = "MyEndpoint_" }; - var endpoint = new SqlPersistenceEndpoint(sqlOptions); + var endpoint = new SqlPersistenceEndpoint(TestHelpers.CreateTestConfiguration(), sqlOptions); try { @@ -114,7 +114,7 @@ public async Task Endpoint_WithSqlPersistence_AndNullTablePrefix_ShouldUseEndpoi ConnectionString = "Server=localhost;Database=TestDb;Trusted_Connection=true;", TablePrefix = null }; - var endpoint = new SqlPersistenceEndpoint(sqlOptions); + var endpoint = new SqlPersistenceEndpoint(TestHelpers.CreateTestConfiguration(), sqlOptions); try { @@ -140,7 +140,7 @@ public async Task Endpoint_WithSqlPersistence_AndSagaPersistenceEnabled_ShouldCo ConnectionString = "Server=localhost;Database=TestDb;Trusted_Connection=true;", EnableSagaPersistence = true }; - var endpoint = new SqlPersistenceEndpoint(sqlOptions); + var endpoint = new SqlPersistenceEndpoint(TestHelpers.CreateTestConfiguration(), sqlOptions); try { @@ -167,7 +167,7 @@ public async Task Endpoint_WithSqlPersistence_AndSubscriptionStorageEnabled_Shou EnableSubscriptionStorage = true, SubscriptionCachePeriod = TimeSpan.FromSeconds(10) }; - var endpoint = new SqlPersistenceEndpoint(sqlOptions); + var endpoint = new SqlPersistenceEndpoint(TestHelpers.CreateTestConfiguration(), sqlOptions); try { @@ -192,7 +192,7 @@ public async Task Endpoint_WithSqlPersistence_AndNullConnectionString_ShouldThro { ConnectionString = null }; - var endpoint = new SqlPersistenceEndpoint(sqlOptions); + var endpoint = new SqlPersistenceEndpoint(TestHelpers.CreateTestConfiguration(), sqlOptions); // Act var act = async () => await endpoint.StartAsync(CancellationToken.None); @@ -213,7 +213,7 @@ public async Task Endpoint_WithSqlPersistence_AndEmptyConnectionString_ShouldThr { ConnectionString = string.Empty }; - var endpoint = new SqlPersistenceEndpoint(sqlOptions); + var endpoint = new SqlPersistenceEndpoint(TestHelpers.CreateTestConfiguration(), sqlOptions); // Act var act = async () => await endpoint.StartAsync(CancellationToken.None); diff --git a/src/ClearHostedEndpoint.Tests/TestEndpoints.cs b/src/ClearHostedEndpoint.Tests/TestEndpoints.cs index d8b09bd..d21f43b 100644 --- a/src/ClearHostedEndpoint.Tests/TestEndpoints.cs +++ b/src/ClearHostedEndpoint.Tests/TestEndpoints.cs @@ -1,3 +1,4 @@ +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using System.Data; using System.Data.Common; @@ -21,14 +22,16 @@ public class TestEndpoint : ClearMeasure.HostedEndpoint.ClearHostedEndpoint private readonly SqlPersistenceOptions? _customSqlPersistenceOptions; private readonly Action? _transportConfigurator; - public TestEndpoint( - EndpointOptions? endpointOptions = null, - SqlPersistenceOptions? sqlPersistenceOptions = null, - Action? transportConfigurator = null) - { - _customEndpointOptions = endpointOptions; - _customSqlPersistenceOptions = sqlPersistenceOptions; - _transportConfigurator = transportConfigurator; + public TestEndpoint( + IConfiguration? configuration = null, + EndpointOptions? endpointOptions = null, + SqlPersistenceOptions? sqlPersistenceOptions = null, + Action? transportConfigurator = null) + : base(configuration ?? new ConfigurationBuilder().Build()) + { + _customEndpointOptions = endpointOptions; + _customSqlPersistenceOptions = sqlPersistenceOptions; + _transportConfigurator = transportConfigurator; } protected override EndpointOptions EndpointOptions => _customEndpointOptions ?? base.EndpointOptions; @@ -90,8 +93,11 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) /// /// Test endpoint that throws an exception during transport configuration. /// -public class FaultyTransportEndpoint : ClearMeasure.HostedEndpoint.ClearHostedEndpoint -{ +public class FaultyTransportEndpoint : ClearMeasure.HostedEndpoint.ClearHostedEndpoint +{ + public FaultyTransportEndpoint(IConfiguration configuration) : base(configuration) + { + } protected override void ConfigureTransport(EndpointConfiguration endpointConfiguration) { throw new InvalidOperationException("Transport configuration failed"); @@ -105,9 +111,9 @@ public class CustomNamedEndpoint : ClearMeasure.HostedEndpoint.ClearHostedEndpoi { private readonly string _endpointName; - public CustomNamedEndpoint(string endpointName) - { - _endpointName = endpointName; + public CustomNamedEndpoint(IConfiguration configuration, string endpointName) : base(configuration) + { + _endpointName = endpointName; } protected override EndpointOptions EndpointOptions => new() { EndpointName = _endpointName }; @@ -125,9 +131,9 @@ public class SqlPersistenceEndpoint : ClearMeasure.HostedEndpoint.ClearHostedEnd { private readonly SqlPersistenceOptions _sqlOptions; - public SqlPersistenceEndpoint(SqlPersistenceOptions sqlOptions) - { - _sqlOptions = sqlOptions; + public SqlPersistenceEndpoint(IConfiguration configuration, SqlPersistenceOptions sqlOptions) : base(configuration) + { + _sqlOptions = sqlOptions; } protected override SqlPersistenceOptions? SqlPersistenceOptions => _sqlOptions; @@ -196,9 +202,13 @@ protected override DbCommand CreateDbCommand() /// /// Test endpoint with custom recoverability configuration. /// -public class CustomRecoverabilityEndpoint : ClearMeasure.HostedEndpoint.ClearHostedEndpoint -{ - public int CustomImmediateRetries { get; set; } = 5; +public class CustomRecoverabilityEndpoint : ClearMeasure.HostedEndpoint.ClearHostedEndpoint +{ + public CustomRecoverabilityEndpoint(IConfiguration configuration) : base(configuration) + { + } + + public int CustomImmediateRetries { get; set; } = 5; public int CustomDelayedRetries { get; set; } = 10; protected override void ConfigureTransport(EndpointConfiguration endpointConfiguration) @@ -217,8 +227,11 @@ protected override void ConfigureRecoverability(EndpointConfiguration endpointCo /// /// Test endpoint that registers custom dependencies. /// -public class DependencyInjectionEndpoint : ClearMeasure.HostedEndpoint.ClearHostedEndpoint -{ +public class DependencyInjectionEndpoint : ClearMeasure.HostedEndpoint.ClearHostedEndpoint +{ + public DependencyInjectionEndpoint(IConfiguration configuration) : base(configuration) + { + } protected override void ConfigureTransport(EndpointConfiguration endpointConfiguration) { endpointConfiguration.UseTransport(); diff --git a/src/ClearHostedEndpoint.Tests/TestHelpers.cs b/src/ClearHostedEndpoint.Tests/TestHelpers.cs new file mode 100644 index 0000000..9ded769 --- /dev/null +++ b/src/ClearHostedEndpoint.Tests/TestHelpers.cs @@ -0,0 +1,17 @@ +namespace ClearHostedEndpoint.Tests; + +/// +/// Helper methods for tests. +/// +public static class TestHelpers +{ + /// + /// Creates an empty test configuration. + /// + public static IConfiguration CreateTestConfiguration() + { + return new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary()) + .Build(); + } +} diff --git a/src/ClearHostedEndpoint/ClearHostedEndpoint.cs b/src/ClearHostedEndpoint/ClearHostedEndpoint.cs index 99647e5..c562cd7 100644 --- a/src/ClearHostedEndpoint/ClearHostedEndpoint.cs +++ b/src/ClearHostedEndpoint/ClearHostedEndpoint.cs @@ -4,6 +4,7 @@ using ClearMeasure.HostedService; using Microsoft.Data.SqlClient; using ClearMeasure.HostedEndpoint.Configuration; +using Microsoft.Extensions.Configuration; namespace ClearMeasure.HostedEndpoint; @@ -16,6 +17,10 @@ public abstract class ClearHostedEndpoint : ClearHostedService private IEndpointInstance? _endpointInstance; private IServiceCollection? _nsbServiceCollection; + protected ClearHostedEndpoint(IConfiguration configuration) : base(configuration) + { + } + /// /// Gets the NServiceBus endpoint instance. Only available after StartAsync has completed. /// diff --git a/src/ClearHostedService.Tests/ClearHostedServiceTests.cs b/src/ClearHostedService.Tests/ClearHostedServiceTests.cs index 18f4965..7db29aa 100644 --- a/src/ClearHostedService.Tests/ClearHostedServiceTests.cs +++ b/src/ClearHostedService.Tests/ClearHostedServiceTests.cs @@ -1,19 +1,24 @@ -using ClearMeasure.HostedService; -using FluentAssertions; -using Microsoft.Extensions.DependencyInjection; -using Xunit; - -namespace QuickHostedService.Tests; - -/// -/// Test service for testing ClearHostedService functionality. -/// -public class TestHostedService : ClearHostedService -{ - public bool OnStartingAsyncCalled { get; private set; } - public bool OnStoppingAsyncCalled { get; private set; } - public bool ExecuteAsyncCalled { get; private set; } - public bool RegisterDependencyInjectionCalled { get; private set; } +using ClearMeasure.HostedService; +using FluentAssertions; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Xunit; + +namespace QuickHostedService.Tests; + +/// +/// Test service for testing ClearHostedService functionality. +/// +public class TestHostedService : ClearHostedService +{ + public bool OnStartingAsyncCalled { get; private set; } + public bool OnStoppingAsyncCalled { get; private set; } + public bool ExecuteAsyncCalled { get; private set; } + public bool RegisterDependencyInjectionCalled { get; private set; } + + public TestHostedService(IConfiguration configuration) : base(configuration) + { + } protected override void RegisterDependencyInjection(IServiceCollection services) { @@ -61,13 +66,20 @@ public void DoWork() } } -public class ClearHostedServiceTests -{ - [Fact] - public async Task StartAsync_ShouldCallLifecycleMethods_InCorrectOrder() - { - // Arrange - var service = new TestHostedService(); +public class ClearHostedServiceTests +{ + private static IConfiguration CreateTestConfiguration() + { + return new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary()) + .Build(); + } + + [Fact] + public async Task StartAsync_ShouldCallLifecycleMethods_InCorrectOrder() + { + // Arrange + var service = new TestHostedService(CreateTestConfiguration()); // Act await service.StartAsync(CancellationToken.None); @@ -81,11 +93,11 @@ public async Task StartAsync_ShouldCallLifecycleMethods_InCorrectOrder() service.OnStoppingAsyncCalled.Should().BeTrue(); } - [Fact] - public async Task StartAsync_ShouldRegisterDependencies_Successfully() - { - // Arrange - var service = new TestHostedService(); + [Fact] + public async Task StartAsync_ShouldRegisterDependencies_Successfully() + { + // Arrange + var service = new TestHostedService(CreateTestConfiguration()); // Act await service.StartAsync(CancellationToken.None); @@ -96,11 +108,11 @@ public async Task StartAsync_ShouldRegisterDependencies_Successfully() service.ExecuteAsyncCalled.Should().BeTrue(); } - [Fact] - public async Task StopAsync_ShouldCallOnStoppingAsync() - { - // Arrange - var service = new TestHostedService(); + [Fact] + public async Task StopAsync_ShouldCallOnStoppingAsync() + { + // Arrange + var service = new TestHostedService(CreateTestConfiguration()); await service.StartAsync(CancellationToken.None); await Task.Delay(100); @@ -111,11 +123,11 @@ public async Task StopAsync_ShouldCallOnStoppingAsync() service.OnStoppingAsyncCalled.Should().BeTrue(); } - [Fact] - public async Task ExecuteAsync_ShouldRespectCancellationToken() - { - // Arrange - var service = new TestHostedService(); + [Fact] + public async Task ExecuteAsync_ShouldRespectCancellationToken() + { + // Arrange + var service = new TestHostedService(CreateTestConfiguration()); await service.StartAsync(CancellationToken.None); await Task.Delay(50); @@ -126,11 +138,11 @@ public async Task ExecuteAsync_ShouldRespectCancellationToken() service.OnStoppingAsyncCalled.Should().BeTrue(); } - [Fact] - public async Task ServiceProvider_ShouldResolveRegisteredServices() - { - // Arrange - var service = new TestHostedService(); + [Fact] + public async Task ServiceProvider_ShouldResolveRegisteredServices() + { + // Arrange + var service = new TestHostedService(CreateTestConfiguration()); // Act await service.StartAsync(CancellationToken.None); @@ -141,22 +153,22 @@ public async Task ServiceProvider_ShouldResolveRegisteredServices() service.ExecuteAsyncCalled.Should().BeTrue(); } - [Fact] - public void Dispose_ShouldNotThrow() - { - // Arrange - var service = new TestHostedService(); + [Fact] + public void Dispose_ShouldNotThrow() + { + // Arrange + var service = new TestHostedService(CreateTestConfiguration()); // Act & Assert var act = () => service.Dispose(); act.Should().NotThrow(); } - [Fact] - public async Task MultipleStartStop_ShouldWork() - { - // Arrange - var service = new TestHostedService(); + [Fact] + public async Task MultipleStartStop_ShouldWork() + { + // Arrange + var service = new TestHostedService(CreateTestConfiguration()); // Act await service.StartAsync(CancellationToken.None); diff --git a/src/ClearHostedService/ClearHostedService.cs b/src/ClearHostedService/ClearHostedService.cs index bbe335a..cd5b50a 100644 --- a/src/ClearHostedService/ClearHostedService.cs +++ b/src/ClearHostedService/ClearHostedService.cs @@ -1,7 +1,7 @@ using ClearMeasure.HostedService.Configuration; using ClearMeasure.HostedService.Exceptions; using ClearMeasure.HostedService.Interfaces; - +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; @@ -18,12 +18,18 @@ namespace ClearMeasure.HostedService; /// public abstract class ClearHostedService : IHostedService, IHostedServiceLifecycle, IDisposable { - private IServiceProvider? _serviceProvider; + protected IServiceProvider? _serviceProvider; + protected IConfiguration Configuration; private ILogger? _logger; private Task? _executingTask; private CancellationTokenSource? _stoppingCts; private bool _disposed; + protected ClearHostedService(IConfiguration configuration) + { + Configuration = configuration; + } + /// /// Gets the service provider for this hosted service instance. /// Use this to resolve dependencies registered in . diff --git a/src/MultiServiceQuickStart.slnx b/src/MultiServiceQuickStart.slnx index c79e4bd..b92620e 100644 --- a/src/MultiServiceQuickStart.slnx +++ b/src/MultiServiceQuickStart.slnx @@ -1,6 +1,7 @@ + @@ -20,6 +21,13 @@ + + + + + + + diff --git a/src/examples/DataProcessorService/DataProcessorHostedService.cs b/src/examples/DataProcessorService/DataProcessorHostedService.cs index e766f98..cbad195 100644 --- a/src/examples/DataProcessorService/DataProcessorHostedService.cs +++ b/src/examples/DataProcessorService/DataProcessorHostedService.cs @@ -1,16 +1,20 @@ -using ClearMeasure.HostedService; -using DataProcessorService.Models; -using DataProcessorService.Services; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; - -namespace DataProcessorService; - -/// -/// A data processor service that demonstrates dependency injection and scoped services. -/// -public class DataProcessorHostedService : ClearHostedService -{ +using ClearMeasure.HostedService; +using DataProcessorService.Models; +using DataProcessorService.Services; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; + +namespace DataProcessorService; + +/// +/// A data processor service that demonstrates dependency injection and scoped services. +/// +public class DataProcessorHostedService : ClearHostedService +{ + public DataProcessorHostedService(IConfiguration configuration) : base(configuration) + { + } protected override void RegisterDependencyInjection(IServiceCollection services) { // Register configuration diff --git a/src/examples/NServiceBusEndpoint/OrderProcessingEndpoint.cs b/src/examples/NServiceBusEndpoint/OrderProcessingEndpoint.cs index e7a54e2..2107d06 100644 --- a/src/examples/NServiceBusEndpoint/OrderProcessingEndpoint.cs +++ b/src/examples/NServiceBusEndpoint/OrderProcessingEndpoint.cs @@ -1,16 +1,19 @@ -using ClearMeasure.HostedEndpoint; -using ClearMeasure.HostedEndpoint.Configuration; - -using NServiceBus; - -namespace NServiceBusEndpoint; - -/// -/// An example NServiceBus endpoint that processes order-related messages. -/// Demonstrates usage of QuickHostedEndpoint with Learning Transport. -/// -public class OrderProcessingEndpoint : ClearHostedEndpoint -{ +using ClearMeasure.HostedEndpoint; +using ClearMeasure.HostedEndpoint.Configuration; +using Microsoft.Extensions.Configuration; +using NServiceBus; + +namespace NServiceBusEndpoint; + +/// +/// An example NServiceBus endpoint that processes order-related messages. +/// Demonstrates usage of QuickHostedEndpoint with Learning Transport. +/// +public class OrderProcessingEndpoint : ClearHostedEndpoint +{ + public OrderProcessingEndpoint(IConfiguration configuration) : base(configuration) + { + } /// /// Configure endpoint options for the order processing endpoint. /// diff --git a/src/examples/NServiceBusWebApp/NServiceBusWebApp.csproj b/src/examples/NServiceBusWebApp/NServiceBusWebApp.csproj index 8d62c19..b489024 100644 --- a/src/examples/NServiceBusWebApp/NServiceBusWebApp.csproj +++ b/src/examples/NServiceBusWebApp/NServiceBusWebApp.csproj @@ -11,4 +11,8 @@ + + + + diff --git a/src/examples/ScheduledTaskService/ScheduledTaskHostedService.cs b/src/examples/ScheduledTaskService/ScheduledTaskHostedService.cs index 1853fb6..ed84363 100644 --- a/src/examples/ScheduledTaskService/ScheduledTaskHostedService.cs +++ b/src/examples/ScheduledTaskService/ScheduledTaskHostedService.cs @@ -1,20 +1,21 @@ -using ClearMeasure.HostedService; - -namespace ScheduledTaskService; - -/// -/// A hosted service that executes tasks on a schedule. -/// -public class ScheduledTaskHostedService : ClearHostedService -{ - private readonly TaskSchedule _schedule; - - public ScheduledTaskHostedService() - { - // Schedule daily execution at 2:00 AM - // For demo purposes, we'll schedule it for every minute - var now = DateTime.Now; - _schedule = TaskSchedule.Daily(now.Hour, now.Minute + 1); +using ClearMeasure.HostedService; +using Microsoft.Extensions.Configuration; + +namespace ScheduledTaskService; + +/// +/// A hosted service that executes tasks on a schedule. +/// +public class ScheduledTaskHostedService : ClearHostedService +{ + private readonly TaskSchedule _schedule; + + public ScheduledTaskHostedService(IConfiguration configuration) : base(configuration) + { + // Schedule daily execution at 2:00 AM + // For demo purposes, we'll schedule it for every minute + var now = DateTime.Now; + _schedule = TaskSchedule.Daily(now.Hour, now.Minute + 1); } public override Task OnStartingAsync(CancellationToken cancellationToken) diff --git a/src/examples/SimpleWorker/SimpleWorkerService.cs b/src/examples/SimpleWorker/SimpleWorkerService.cs index 762522d..ad947e5 100644 --- a/src/examples/SimpleWorker/SimpleWorkerService.cs +++ b/src/examples/SimpleWorker/SimpleWorkerService.cs @@ -1,12 +1,16 @@ -using ClearMeasure.HostedService; - -namespace SimpleWorker; - -/// -/// A simple background worker that demonstrates basic usage of ClearHostedService. -/// -public class SimpleWorkerService : ClearHostedService -{ +using ClearMeasure.HostedService; +using Microsoft.Extensions.Configuration; + +namespace SimpleWorker; + +/// +/// A simple background worker that demonstrates basic usage of ClearHostedService. +/// +public class SimpleWorkerService : ClearHostedService +{ + public SimpleWorkerService(IConfiguration configuration) : base(configuration) + { + } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { Logger.Information("SimpleWorkerService is starting...");