diff --git a/Directory.Build.props b/Directory.Build.props
index 64132785d..94fc28d2b 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -6,7 +6,7 @@
MIT
Copyright (c) 2020 Sergio Aquilini
- 2.1.2$(VersionSuffix)
+ 2.2.0$(VersionSuffix)
https://beagle1984.github.io/silverback/
https://github.com/BEagle1984/silverback/
git
diff --git a/docs/_docs/0-introduction/003-releases.md b/docs/_docs/0-introduction/003-releases.md
index 757e39c00..389eb131e 100644
--- a/docs/_docs/0-introduction/003-releases.md
+++ b/docs/_docs/0-introduction/003-releases.md
@@ -4,6 +4,11 @@ permalink: /docs/releases
toc: true
---
+## [2.2.0](https://github.com/BEagle1984/silverback/releases/tag/v2.2.0)
+
+### What's new
+* Allow custom outbound routers to be registered as scoped or transient (instead of singleton only)
+
## [2.1.1](https://github.com/BEagle1984/silverback/releases/tag/v2.1.1)
### What's new
diff --git a/docs/_docs/2-configuration/202-outbound.md b/docs/_docs/2-configuration/202-outbound.md
index 9077f88bf..0e79cf38a 100644
--- a/docs/_docs/2-configuration/202-outbound.md
+++ b/docs/_docs/2-configuration/202-outbound.md
@@ -300,7 +300,3 @@ public class Startup
}
{% endhighlight %}
-
-The outbound routers can only be registered as singleton. If a scoped instance is needed you have to inject the `IServiceScopeFactory` (or `IServiceProvider`).
-{: .notice--note}
-
diff --git a/samples/Examples/src/Silverback.Examples.Main/UseCases/Producing/Kafka/Advanced/CustomRoutingUseCase.cs b/samples/Examples/src/Silverback.Examples.Main/UseCases/Producing/Kafka/Advanced/CustomRoutingUseCase.cs
index 37bc149c8..5b093331c 100644
--- a/samples/Examples/src/Silverback.Examples.Main/UseCases/Producing/Kafka/Advanced/CustomRoutingUseCase.cs
+++ b/samples/Examples/src/Silverback.Examples.Main/UseCases/Producing/Kafka/Advanced/CustomRoutingUseCase.cs
@@ -28,7 +28,7 @@ protected override void ConfigureServices(IServiceCollection services) => servic
.AddSilverback()
.UseModel()
.WithConnectionToMessageBroker(options => options.AddKafka())
- .AddSingletonOutboundRouter();
+ .AddScopedOutboundRouter();
protected override void Configure(BusConfigurator configurator, IServiceProvider serviceProvider) =>
configurator.Connect(endpoints => endpoints
diff --git a/samples/Examples/src/Silverback.Examples.Main/UseCases/Producing/Kafka/HealthCheck/OutboundEndpointsHealthUseCase.cs b/samples/Examples/src/Silverback.Examples.Main/UseCases/Producing/Kafka/HealthCheck/OutboundEndpointsHealthUseCase.cs
index 7dde6aa16..fc3eaf7f5 100644
--- a/samples/Examples/src/Silverback.Examples.Main/UseCases/Producing/Kafka/HealthCheck/OutboundEndpointsHealthUseCase.cs
+++ b/samples/Examples/src/Silverback.Examples.Main/UseCases/Producing/Kafka/HealthCheck/OutboundEndpointsHealthUseCase.cs
@@ -74,7 +74,8 @@ protected override async Task Execute(IServiceProvider serviceProvider)
var result = await new OutboundEndpointsHealthCheckService(
serviceProvider.GetRequiredService(),
- serviceProvider.GetRequiredService()).PingAllEndpoints();
+ serviceProvider.GetRequiredService(),
+ serviceProvider).PingAllEndpoints();
Console.ForegroundColor = Constants.PrimaryColor;
Console.WriteLine(JsonConvert.SerializeObject(result, Formatting.Indented));
diff --git a/src/Silverback.Integration/Messaging/Configuration/BusConfiguratorExtensions.cs b/src/Silverback.Integration/Messaging/Configuration/BusConfiguratorExtensions.cs
index 83cfb159b..9bb8ba194 100644
--- a/src/Silverback.Integration/Messaging/Configuration/BusConfiguratorExtensions.cs
+++ b/src/Silverback.Integration/Messaging/Configuration/BusConfiguratorExtensions.cs
@@ -33,8 +33,7 @@ public static IBrokerCollection Connect(
var endpointsConfigurationBuilder = new EndpointsConfigurationBuilder(
configurator.ServiceProvider.GetRequiredService(),
configurator.ServiceProvider.GetRequiredService>(),
- configurator.ServiceProvider.GetRequiredService(),
- configurator.ServiceProvider);
+ configurator.ServiceProvider.GetRequiredService());
endpointsConfigurationAction?.Invoke(endpointsConfigurationBuilder);
configurator.ServiceProvider.GetServices().ForEach(c =>
diff --git a/src/Silverback.Integration/Messaging/Configuration/EndpointsConfigurationBuilder.cs b/src/Silverback.Integration/Messaging/Configuration/EndpointsConfigurationBuilder.cs
index 619be712c..1c52e37ad 100644
--- a/src/Silverback.Integration/Messaging/Configuration/EndpointsConfigurationBuilder.cs
+++ b/src/Silverback.Integration/Messaging/Configuration/EndpointsConfigurationBuilder.cs
@@ -16,18 +16,15 @@ public class EndpointsConfigurationBuilder : IEndpointsConfigurationBuilder
private readonly IOutboundRoutingConfiguration _outboundRoutingConfiguration;
private readonly IReadOnlyCollection _inboundConnectors;
private readonly ErrorPolicyBuilder _errorPolicyBuilder;
- private readonly IServiceProvider _serviceProvider;
public EndpointsConfigurationBuilder(
IOutboundRoutingConfiguration outboundRoutingConfiguration,
IEnumerable inboundConnectors,
- ErrorPolicyBuilder errorPolicyBuilder,
- IServiceProvider serviceProvider)
+ ErrorPolicyBuilder errorPolicyBuilder)
{
_outboundRoutingConfiguration = outboundRoutingConfiguration;
_inboundConnectors = inboundConnectors.ToList();
_errorPolicyBuilder = errorPolicyBuilder;
- _serviceProvider = serviceProvider;
}
public IEndpointsConfigurationBuilder AddOutbound(IProducerEndpoint endpoint)
@@ -85,8 +82,9 @@ public IEndpointsConfigurationBuilder AddOutbound(
Type routerType,
Type outboundConnectorType)
{
- var router = (IOutboundRouter) _serviceProvider.GetRequiredService(routerType);
- _outboundRoutingConfiguration.Add(messageType, router, outboundConnectorType);
+ _outboundRoutingConfiguration.Add(messageType,
+ serviceProvider => (IOutboundRouter) serviceProvider.GetRequiredService(routerType),
+ outboundConnectorType);
return this;
}
@@ -95,7 +93,7 @@ public IEndpointsConfigurationBuilder AddOutbound(
IOutboundRouter router,
Type outboundConnectorType)
{
- _outboundRoutingConfiguration.Add(messageType, router, outboundConnectorType);
+ _outboundRoutingConfiguration.Add(messageType, _ => router, outboundConnectorType);
return this;
}
diff --git a/src/Silverback.Integration/Messaging/Configuration/ServiceCollectionExtensions.cs b/src/Silverback.Integration/Messaging/Configuration/ServiceCollectionExtensions.cs
index 7ce88ce08..810c20ca7 100644
--- a/src/Silverback.Integration/Messaging/Configuration/ServiceCollectionExtensions.cs
+++ b/src/Silverback.Integration/Messaging/Configuration/ServiceCollectionExtensions.cs
@@ -70,7 +70,8 @@ public static IServiceCollection AddEndpointsConfigurator(
/// A reference to this instance after the operation has completed.
public static IServiceCollection AddSingletonBrokerBehavior(this IServiceCollection services, Type behaviorType)
{
- if (behaviorType == null) throw new ArgumentNullException(nameof(behaviorType));
+ if (behaviorType == null)
+ throw new ArgumentNullException(nameof(behaviorType));
services.AddSingleton(typeof(IBrokerBehavior), behaviorType);
@@ -106,7 +107,8 @@ public static IServiceCollection AddSingletonBrokerBehavior(
this IServiceCollection services,
Func implementationFactory)
{
- if (implementationFactory == null) throw new ArgumentNullException(nameof(implementationFactory));
+ if (implementationFactory == null)
+ throw new ArgumentNullException(nameof(implementationFactory));
services.AddSingleton(typeof(IBrokerBehavior), implementationFactory);
@@ -128,7 +130,8 @@ public static IServiceCollection AddSingletonBrokerBehavior(
this IServiceCollection services,
IBrokerBehavior implementationInstance)
{
- if (implementationInstance == null) throw new ArgumentNullException(nameof(implementationInstance));
+ if (implementationInstance == null)
+ throw new ArgumentNullException(nameof(implementationInstance));
services.AddSingleton(typeof(IBrokerBehavior), implementationInstance);
@@ -137,6 +140,128 @@ public static IServiceCollection AddSingletonBrokerBehavior(
#endregion
+ #region AddTransientOutboundRouter
+
+ ///
+ /// Adds a transient outbound router of the type specified in to the
+ /// specified .
+ ///
+ ///
+ /// The to add the
+ /// service to.
+ ///
+ /// The type of the outbound router to register and the implementation to use.
+ /// A reference to this instance after the operation has completed.
+ public static IServiceCollection AddTransientOutboundRouter(this IServiceCollection services, Type routerType)
+ {
+ if (routerType == null)
+ throw new ArgumentNullException(nameof(routerType));
+
+ services.AddTransient(routerType);
+
+ return services;
+ }
+
+ ///
+ /// Adds a transient outbound router of the type specified in to the
+ /// specified .
+ ///
+ /// The type of the outbound router to add.
+ ///
+ /// The to add the
+ /// service to.
+ ///
+ /// A reference to this instance after the operation has completed.
+ public static IServiceCollection AddTransientOutboundRouter(this IServiceCollection services)
+ where TRouter : class, IOutboundRouter =>
+ AddTransientOutboundRouter(services, typeof(TRouter));
+
+ ///
+ /// Adds a transient outbound router with a
+ /// factory specified in to the
+ /// specified .
+ ///
+ ///
+ /// The to add the
+ /// service to.
+ ///
+ /// The factory that creates the service.
+ /// A reference to this instance after the operation has completed.
+ public static IServiceCollection AddTransientOutboundRouter(
+ this IServiceCollection services,
+ Func implementationFactory)
+ {
+ if (implementationFactory == null)
+ throw new ArgumentNullException(nameof(implementationFactory));
+
+ services.AddTransient(implementationFactory);
+
+ return services;
+ }
+
+ #endregion
+
+ #region AddScopedOutboundRouter
+
+ ///
+ /// Adds a scoped outbound router of the type specified in to the
+ /// specified .
+ ///
+ ///
+ /// The to add the
+ /// service to.
+ ///
+ /// The type of the outbound router to register and the implementation to use.
+ /// A reference to this instance after the operation has completed.
+ public static IServiceCollection AddScopedOutboundRouter(this IServiceCollection services, Type routerType)
+ {
+ if (routerType == null)
+ throw new ArgumentNullException(nameof(routerType));
+
+ services.AddScoped(routerType);
+
+ return services;
+ }
+
+ ///
+ /// Adds a scoped outbound router of the type specified in to the
+ /// specified .
+ ///
+ /// The type of the outbound router to add.
+ ///
+ /// The to add the
+ /// service to.
+ ///
+ /// A reference to this instance after the operation has completed.
+ public static IServiceCollection AddScopedOutboundRouter(this IServiceCollection services)
+ where TRouter : class, IOutboundRouter =>
+ AddScopedOutboundRouter(services, typeof(TRouter));
+
+ ///
+ /// Adds a scoped outbound router with a
+ /// factory specified in to the
+ /// specified .
+ ///
+ ///
+ /// The to add the
+ /// service to.
+ ///
+ /// The factory that creates the service.
+ /// A reference to this instance after the operation has completed.
+ public static IServiceCollection AddScopedOutboundRouter(
+ this IServiceCollection services,
+ Func implementationFactory)
+ {
+ if (implementationFactory == null)
+ throw new ArgumentNullException(nameof(implementationFactory));
+
+ services.AddScoped(implementationFactory);
+
+ return services;
+ }
+
+ #endregion
+
#region AddSingletonOutboundRouter
///
@@ -151,7 +276,8 @@ public static IServiceCollection AddSingletonBrokerBehavior(
/// A reference to this instance after the operation has completed.
public static IServiceCollection AddSingletonOutboundRouter(this IServiceCollection services, Type routerType)
{
- if (routerType == null) throw new ArgumentNullException(nameof(routerType));
+ if (routerType == null)
+ throw new ArgumentNullException(nameof(routerType));
services.AddSingleton(routerType);
@@ -187,7 +313,8 @@ public static IServiceCollection AddSingletonOutboundRouter(
this IServiceCollection services,
Func implementationFactory)
{
- if (implementationFactory == null) throw new ArgumentNullException(nameof(implementationFactory));
+ if (implementationFactory == null)
+ throw new ArgumentNullException(nameof(implementationFactory));
services.AddSingleton(implementationFactory);
@@ -209,7 +336,8 @@ public static IServiceCollection AddSingletonOutboundRouter(
this IServiceCollection services,
IOutboundRouter implementationInstance)
{
- if (implementationInstance == null) throw new ArgumentNullException(nameof(implementationInstance));
+ if (implementationInstance == null)
+ throw new ArgumentNullException(nameof(implementationInstance));
services.AddSingleton(implementationInstance);
diff --git a/src/Silverback.Integration/Messaging/Configuration/SilverbackBuilderExtensions.cs b/src/Silverback.Integration/Messaging/Configuration/SilverbackBuilderExtensions.cs
index b496427b6..c7788a2bd 100644
--- a/src/Silverback.Integration/Messaging/Configuration/SilverbackBuilderExtensions.cs
+++ b/src/Silverback.Integration/Messaging/Configuration/SilverbackBuilderExtensions.cs
@@ -169,6 +169,100 @@ public static ISilverbackBuilder AddSingletonBrokerBehavior(
#endregion
+ #region AddTransientOutboundRouter
+
+ ///
+ /// Adds a transient outbound router of the type specified in to the
+ /// .
+ ///
+ ///
+ /// The type of the outbound router to register and the implementation to use.
+ /// A reference to this instance after the operation has completed.
+ public static ISilverbackBuilder AddTransientOutboundRouter(this ISilverbackBuilder builder, Type routerType)
+ {
+ builder.Services.AddTransientOutboundRouter(routerType);
+ return builder;
+ }
+
+ ///
+ /// Adds a transient outbound router of the type specified in to the
+ /// .
+ ///
+ /// The type of the outbound router to add.
+ ///
+ /// A reference to this instance after the operation has completed.
+ public static ISilverbackBuilder AddTransientOutboundRouter(this ISilverbackBuilder builder)
+ where TRouter : class, IOutboundRouter
+ {
+ builder.Services.AddTransientOutboundRouter();
+ return builder;
+ }
+
+ ///
+ /// Adds a transient outbound router with a
+ /// factory specified in to the
+ /// .
+ ///
+ ///
+ /// The factory that creates the service.
+ /// A reference to this instance after the operation has completed.
+ public static ISilverbackBuilder AddTransientOutboundRouter(
+ this ISilverbackBuilder builder,
+ Func implementationFactory)
+ {
+ builder.Services.AddTransientOutboundRouter(implementationFactory);
+ return builder;
+ }
+
+ #endregion
+
+ #region AddScopedOutboundRouter
+
+ ///
+ /// Adds a scoped outbound router of the type specified in to the
+ /// .
+ ///
+ ///
+ /// The type of the outbound router to register and the implementation to use.
+ /// A reference to this instance after the operation has completed.
+ public static ISilverbackBuilder AddScopedOutboundRouter(this ISilverbackBuilder builder, Type routerType)
+ {
+ builder.Services.AddScopedOutboundRouter(routerType);
+ return builder;
+ }
+
+ ///
+ /// Adds a scoped outbound router of the type specified in to the
+ /// .
+ ///
+ /// The type of the outbound router to add.
+ ///
+ /// A reference to this instance after the operation has completed.
+ public static ISilverbackBuilder AddScopedOutboundRouter(this ISilverbackBuilder builder)
+ where TRouter : class, IOutboundRouter
+ {
+ builder.Services.AddScopedOutboundRouter();
+ return builder;
+ }
+
+ ///
+ /// Adds a scoped outbound router with a
+ /// factory specified in to the
+ /// .
+ ///
+ ///
+ /// The factory that creates the service.
+ /// A reference to this instance after the operation has completed.
+ public static ISilverbackBuilder AddScopedOutboundRouter(
+ this ISilverbackBuilder builder,
+ Func implementationFactory)
+ {
+ builder.Services.AddScopedOutboundRouter(implementationFactory);
+ return builder;
+ }
+
+ #endregion
+
#region AddSingletonOutboundRouter
///
diff --git a/src/Silverback.Integration/Messaging/Connectors/Behaviors/OutboundRouterBehavior.cs b/src/Silverback.Integration/Messaging/Connectors/Behaviors/OutboundRouterBehavior.cs
index 17999b2a4..0a6d67dc1 100644
--- a/src/Silverback.Integration/Messaging/Connectors/Behaviors/OutboundRouterBehavior.cs
+++ b/src/Silverback.Integration/Messaging/Connectors/Behaviors/OutboundRouterBehavior.cs
@@ -2,6 +2,7 @@
// This code is licensed under MIT license (see LICENSE file for details)
using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
@@ -20,6 +21,9 @@ public class OutboundRouterBehavior : IBehavior, ISorted
private readonly IServiceProvider _serviceProvider;
private readonly IOutboundRoutingConfiguration _routing;
+ private readonly ConcurrentDictionary _routers =
+ new ConcurrentDictionary();
+
public OutboundRouterBehavior(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
@@ -62,7 +66,8 @@ await _serviceProvider
private IEnumerable CreateOutboundEnvelope(object message, IOutboundRoute route)
{
var headers = new MessageHeaderCollection();
- var endpoints = route.Router.GetDestinationEndpoints(message, headers);
+ var router = _routers.GetOrAdd(route, _ => route.GetOutboundRouter(_serviceProvider));
+ var endpoints = router.GetDestinationEndpoints(message, headers);
foreach (var endpoint in endpoints)
{
diff --git a/src/Silverback.Integration/Messaging/Connectors/IOutboundRoute.cs b/src/Silverback.Integration/Messaging/Connectors/IOutboundRoute.cs
index 6c2f414b1..34db1782a 100644
--- a/src/Silverback.Integration/Messaging/Connectors/IOutboundRoute.cs
+++ b/src/Silverback.Integration/Messaging/Connectors/IOutboundRoute.cs
@@ -16,13 +16,13 @@ public interface IOutboundRoute
Type MessageType { get; }
///
- /// Gets the instance of to be used to determine the destination endpoint.
+ /// Gets the type of the to be used when publishing these messages.
///
- IOutboundRouter Router { get; }
+ Type OutboundConnectorType { get; }
///
- /// Gets the type of the to be used when publishing these messages.
+ /// Returns the instance of to be used to determine the destination endpoint.
///
- Type OutboundConnectorType { get; }
+ IOutboundRouter GetOutboundRouter(IServiceProvider serviceProvider);
}
}
\ No newline at end of file
diff --git a/src/Silverback.Integration/Messaging/Connectors/IOutboundRoutingConfiguration.cs b/src/Silverback.Integration/Messaging/Connectors/IOutboundRoutingConfiguration.cs
index f0d42c808..c2a76fcc6 100644
--- a/src/Silverback.Integration/Messaging/Connectors/IOutboundRoutingConfiguration.cs
+++ b/src/Silverback.Integration/Messaging/Connectors/IOutboundRoutingConfiguration.cs
@@ -29,25 +29,34 @@ public interface IOutboundRoutingConfiguration
///
/// The type of the messages to be routed.
///
- ///
- /// The router to be used to determine the destination endpoint.
+ ///
+ /// The factory method to be used to get the instance of to be used to
+ /// determine the destination endpoint.
///
///
/// The type of the to be used.
/// If null, the default will be used.
///
- IOutboundRoutingConfiguration Add(IOutboundRouter router, Type outboundConnectorType = null);
+ IOutboundRoutingConfiguration Add(
+ Func outboundRouterFactory,
+ Type outboundConnectorType = null);
///
/// Add an outbound routing rule.
///
/// The type of the messages to be routed.
- /// The router to be used to determine the destination endpoint.
+ ///
+ /// The factory method to be used to get the instance of to be used to
+ /// determine the destination endpoint.
+ ///
///
/// The type of the to be used.
/// If null, the default will be used.
///
- IOutboundRoutingConfiguration Add(Type messageType, IOutboundRouter router, Type outboundConnectorType = null);
+ IOutboundRoutingConfiguration Add(
+ Type messageType,
+ Func outboundRouterFactory,
+ Type outboundConnectorType = null);
///
/// Returns the outbound routes that apply to the specified message.
diff --git a/src/Silverback.Integration/Messaging/Connectors/OutboundRoute.cs b/src/Silverback.Integration/Messaging/Connectors/OutboundRoute.cs
index dbe14972a..a22ee586a 100644
--- a/src/Silverback.Integration/Messaging/Connectors/OutboundRoute.cs
+++ b/src/Silverback.Integration/Messaging/Connectors/OutboundRoute.cs
@@ -8,17 +8,20 @@ namespace Silverback.Messaging.Connectors
///
public class OutboundRoute : IOutboundRoute
{
- public OutboundRoute(Type messageType, IOutboundRouter router, Type outboundConnectorType)
+ private readonly Func _outboundRouterFactory;
+
+ public OutboundRoute(Type messageType, Func outboundRouterFactory, Type outboundConnectorType)
{
MessageType = messageType;
- Router = router;
+ _outboundRouterFactory = outboundRouterFactory;
OutboundConnectorType = outboundConnectorType;
}
public Type MessageType { get; }
- public IOutboundRouter Router { get; }
-
public Type OutboundConnectorType { get; }
+
+ public IOutboundRouter GetOutboundRouter(IServiceProvider serviceProvider) =>
+ _outboundRouterFactory.Invoke(serviceProvider);
}
}
\ No newline at end of file
diff --git a/src/Silverback.Integration/Messaging/Connectors/OutboundRoutingConfiguration.cs b/src/Silverback.Integration/Messaging/Connectors/OutboundRoutingConfiguration.cs
index a32bb5161..e57370bd6 100644
--- a/src/Silverback.Integration/Messaging/Connectors/OutboundRoutingConfiguration.cs
+++ b/src/Silverback.Integration/Messaging/Connectors/OutboundRoutingConfiguration.cs
@@ -16,15 +16,15 @@ public class OutboundRoutingConfiguration : IOutboundRoutingConfiguration
public IEnumerable Routes => _routes.AsReadOnly();
- public IOutboundRoutingConfiguration Add(IOutboundRouter router, Type outboundConnectorType) =>
- Add(typeof(TMessage), router, outboundConnectorType);
+ public IOutboundRoutingConfiguration Add(Func outboundRouterFactory, Type outboundConnectorType) =>
+ Add(typeof(TMessage), outboundRouterFactory, outboundConnectorType);
public IOutboundRoutingConfiguration Add(
Type messageType,
- IOutboundRouter router,
+ Func outboundRouterFactory,
Type outboundConnectorType = null)
{
- _routes.Add(new OutboundRoute(messageType, router, outboundConnectorType));
+ _routes.Add(new OutboundRoute(messageType, outboundRouterFactory, outboundConnectorType));
return this;
}
diff --git a/src/Silverback.Integration/Messaging/HealthChecks/OutboundEndpointsHealthCheckService.cs b/src/Silverback.Integration/Messaging/HealthChecks/OutboundEndpointsHealthCheckService.cs
index c94b4480b..3b6305259 100644
--- a/src/Silverback.Integration/Messaging/HealthChecks/OutboundEndpointsHealthCheckService.cs
+++ b/src/Silverback.Integration/Messaging/HealthChecks/OutboundEndpointsHealthCheckService.cs
@@ -14,14 +14,17 @@ public class OutboundEndpointsHealthCheckService : IOutboundEndpointsHealthCheck
{
private readonly IOutboundRoutingConfiguration _outboundRoutingConfiguration;
private readonly IBrokerCollection _brokerCollection;
+ private readonly IServiceProvider _serviceProvider;
public OutboundEndpointsHealthCheckService(
IOutboundRoutingConfiguration outboundRoutingConfiguration,
- IBrokerCollection brokerCollection)
+ IBrokerCollection brokerCollection,
+ IServiceProvider serviceProvider)
{
_outboundRoutingConfiguration = outboundRoutingConfiguration ??
throw new ArgumentNullException(nameof(outboundRoutingConfiguration));
_brokerCollection = brokerCollection ?? throw new ArgumentNullException(nameof(brokerCollection));
+ _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
}
public async Task> PingAllEndpoints()
@@ -30,7 +33,7 @@ public async Task> PingAllEndpoints()
return Enumerable.Empty();
var tasks = _outboundRoutingConfiguration.Routes
- .SelectMany(route => route.Router.Endpoints
+ .SelectMany(route => route.GetOutboundRouter(_serviceProvider).Endpoints
.Select(async endpoint =>
{
try
diff --git a/tests/Silverback.Integration.Tests/Messaging/Connectors/Behaviors/OutboundRouterBehaviorTests.cs b/tests/Silverback.Integration.Tests/Messaging/Connectors/Behaviors/OutboundRouterBehaviorTests.cs
index cce9d6a20..19c6fab48 100644
--- a/tests/Silverback.Integration.Tests/Messaging/Connectors/Behaviors/OutboundRouterBehaviorTests.cs
+++ b/tests/Silverback.Integration.Tests/Messaging/Connectors/Behaviors/OutboundRouterBehaviorTests.cs
@@ -1,6 +1,7 @@
// Copyright (c) 2020 Sergio Aquilini
// This code is licensed under MIT license (see LICENSE file for details)
+using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
@@ -28,6 +29,7 @@ public class OutboundRouterBehaviorTests
private readonly TestBroker _broker;
private readonly TestOtherBroker _otherBroker;
private readonly TestSubscriber _testSubscriber;
+ private readonly IServiceProvider _serviceProvider;
public OutboundRouterBehaviorTests()
{
@@ -49,14 +51,14 @@ public OutboundRouterBehaviorTests()
services.AddNullLogger();
- var serviceProvider = services.BuildServiceProvider();
+ _serviceProvider = services.BuildServiceProvider();
- _behavior = (OutboundRouterBehavior) serviceProvider.GetServices()
+ _behavior = (OutboundRouterBehavior) _serviceProvider.GetServices()
.First(s => s is OutboundRouterBehavior);
_routingConfiguration =
- (OutboundRoutingConfiguration) serviceProvider.GetRequiredService();
- _broker = serviceProvider.GetRequiredService();
- _otherBroker = serviceProvider.GetRequiredService();
+ (OutboundRoutingConfiguration) _serviceProvider.GetRequiredService();
+ _broker = _serviceProvider.GetRequiredService();
+ _otherBroker = _serviceProvider.GetRequiredService();
}
[Theory, MemberData(nameof(Handle_MultipleMessages_CorrectlyRoutedToEndpoints_TestData))]
@@ -65,11 +67,11 @@ public async Task Handle_MultipleMessages_CorrectlyRoutedToStaticEndpoint(
string[] expectedEndpointNames)
{
_routingConfiguration.Add(
- new StaticOutboundRouter(new TestProducerEndpoint("allMessages")));
+ _ => new StaticOutboundRouter(new TestProducerEndpoint("allMessages")));
_routingConfiguration.Add(
- new StaticOutboundRouter(new TestProducerEndpoint("allEvents")));
- _routingConfiguration.Add(new StaticOutboundRouter(new TestProducerEndpoint("eventOne")));
- _routingConfiguration.Add(new StaticOutboundRouter(new TestProducerEndpoint("eventTwo")));
+ _ => new StaticOutboundRouter(new TestProducerEndpoint("allEvents")));
+ _routingConfiguration.Add(_ => new StaticOutboundRouter(new TestProducerEndpoint("eventOne")));
+ _routingConfiguration.Add(_ => new StaticOutboundRouter(new TestProducerEndpoint("eventTwo")));
await _behavior.Handle(new[] { message }, Task.FromResult);
await _outboundQueue.Commit();
@@ -82,7 +84,7 @@ public async Task Handle_MultipleMessages_CorrectlyRoutedToStaticEndpoint(
}
var notExpectedEndpointNames = _routingConfiguration
- .Routes.Select(r => r.Router.Endpoints.First().Name)
+ .Routes.Select(r => r.GetOutboundRouter(_serviceProvider).Endpoints.First().Name)
.Where(r => !expectedEndpointNames.Contains(r));
foreach (var notExpectedEndpointName in notExpectedEndpointNames)
@@ -101,7 +103,7 @@ public async Task Handle_MultipleMessages_CorrectlyRoutedToStaticEndpoint(
[Fact]
public async Task Handle_Message_CorrectlyRoutedToDefaultConnector()
{
- _routingConfiguration.Add(new StaticOutboundRouter(new TestProducerEndpoint("eventOne")));
+ _routingConfiguration.Add(_ => new StaticOutboundRouter(new TestProducerEndpoint("eventOne")));
await _behavior.Handle(new[] { new TestEventOne() }, Task.FromResult);
await _outboundQueue.Commit();
@@ -114,7 +116,7 @@ public async Task Handle_Message_CorrectlyRoutedToDefaultConnector()
[Fact]
public async Task Handle_Message_CorrectlyRoutedToConnector()
{
- _routingConfiguration.Add(new StaticOutboundRouter(new TestProducerEndpoint("eventOne")),
+ _routingConfiguration.Add(_ => new StaticOutboundRouter(new TestProducerEndpoint("eventOne")),
typeof(OutboundConnector));
await _behavior.Handle(new[] { new TestEventOne() }, Task.FromResult);
@@ -128,7 +130,7 @@ public async Task Handle_Message_CorrectlyRoutedToConnector()
[Fact]
public async Task Handle_Messages_RoutedMessageIsFiltered()
{
- _routingConfiguration.Add(new StaticOutboundRouter(new TestProducerEndpoint("eventOne")),
+ _routingConfiguration.Add(_ => new StaticOutboundRouter(new TestProducerEndpoint("eventOne")),
typeof(OutboundConnector));
var messages =
@@ -141,7 +143,7 @@ public async Task Handle_Messages_RoutedMessageIsFiltered()
[Fact]
public async Task Handle_Messages_RoutedMessageIsRepublishedWithoutAutoUnwrap()
{
- _routingConfiguration.Add(new StaticOutboundRouter(new TestProducerEndpoint("eventOne")),
+ _routingConfiguration.Add(_ => new StaticOutboundRouter(new TestProducerEndpoint("eventOne")),
typeof(OutboundConnector));
await _behavior.Handle(new object[] { new TestEventOne(), new TestEventTwo() }, Task.FromResult);
@@ -153,7 +155,7 @@ public async Task Handle_Messages_RoutedMessageIsRepublishedWithoutAutoUnwrap()
public async Task Handle_MessagesWithPublishToInternBusOption_RoutedMessageIsFiltered()
{
_routingConfiguration.PublishOutboundMessagesToInternalBus = true;
- _routingConfiguration.Add(new StaticOutboundRouter(new TestProducerEndpoint("eventOne")),
+ _routingConfiguration.Add(_ => new StaticOutboundRouter(new TestProducerEndpoint("eventOne")),
typeof(OutboundConnector));
var messages =
@@ -167,7 +169,7 @@ public async Task Handle_MessagesWithPublishToInternBusOption_RoutedMessageIsFil
public async Task Handle_MessagesWithPublishToInternBusOption_RoutedMessageIsRepublishedWithAutoUnwrap()
{
_routingConfiguration.PublishOutboundMessagesToInternalBus = true;
- _routingConfiguration.Add(new StaticOutboundRouter(new TestProducerEndpoint("eventOne")),
+ _routingConfiguration.Add(_ => new StaticOutboundRouter(new TestProducerEndpoint("eventOne")),
typeof(OutboundConnector));
await _behavior.Handle(new object[] { new TestEventOne(), new TestEventTwo() }, Task.FromResult);
@@ -180,7 +182,7 @@ public async Task Handle_MessagesWithPublishToInternBusOption_RoutedMessageIsRep
public async Task Handle_OutboundEnvelopeWithPublishToInternBusOption_OutboundEnvelopeIsNotFiltered()
{
_routingConfiguration.PublishOutboundMessagesToInternalBus = true;
- _routingConfiguration.Add(new StaticOutboundRouter(new TestProducerEndpoint("eventOne")),
+ _routingConfiguration.Add(_ => new StaticOutboundRouter(new TestProducerEndpoint("eventOne")),
typeof(OutboundConnector));
var messages =
@@ -202,7 +204,7 @@ public async Task Handle_UnhandledMessageType_CorrectlyRelayed()
{
var message = new SomeUnhandledMessage { Content = "abc" };
_routingConfiguration.Add(
- new StaticOutboundRouter(new TestProducerEndpoint("eventOne")),
+ _ => new StaticOutboundRouter(new TestProducerEndpoint("eventOne")),
typeof(OutboundConnector));
await _behavior.Handle(new[] { message }, Task.FromResult);
@@ -214,9 +216,9 @@ public async Task Handle_UnhandledMessageType_CorrectlyRelayed()
public async Task Handle_MultipleRoutesToMultipleBrokers_CorrectlyQueued()
{
_routingConfiguration
- .Add(new StaticOutboundRouter(new TestProducerEndpoint("eventOne")))
- .Add(new StaticOutboundRouter(new TestOtherProducerEndpoint("eventTwo")))
- .Add(new StaticOutboundRouter(new TestProducerEndpoint("eventThree")));
+ .Add(_ => new StaticOutboundRouter(new TestProducerEndpoint("eventOne")))
+ .Add(_ => new StaticOutboundRouter(new TestOtherProducerEndpoint("eventTwo")))
+ .Add(_ => new StaticOutboundRouter(new TestProducerEndpoint("eventThree")));
await _behavior.Handle(new[] { new TestEventOne() }, Task.FromResult);
await _behavior.Handle(new[] { new TestEventThree(), }, Task.FromResult);
@@ -234,11 +236,11 @@ public async Task Handle_MultipleRoutesToMultipleBrokers_CorrectlyQueued()
public async Task Handle_MultipleRoutesToMultipleBrokers_CorrectlyRelayed()
{
_routingConfiguration
- .Add(new StaticOutboundRouter(new TestProducerEndpoint("eventOne")),
+ .Add(_ => new StaticOutboundRouter(new TestProducerEndpoint("eventOne")),
typeof(OutboundConnector))
- .Add(new StaticOutboundRouter(new TestOtherProducerEndpoint("eventTwo")),
+ .Add(_ => new StaticOutboundRouter(new TestOtherProducerEndpoint("eventTwo")),
typeof(OutboundConnector))
- .Add(new StaticOutboundRouter(new TestProducerEndpoint("eventThree")),
+ .Add(_ => new StaticOutboundRouter(new TestProducerEndpoint("eventThree")),
typeof(OutboundConnector));
await _behavior.Handle(new[] { new TestEventOne() }, Task.FromResult);
diff --git a/tests/Silverback.Integration.Tests/Messaging/Connectors/OutboundQueueWorkerTests.cs b/tests/Silverback.Integration.Tests/Messaging/Connectors/OutboundQueueWorkerTests.cs
index 1911f9db3..a09144cf2 100644
--- a/tests/Silverback.Integration.Tests/Messaging/Connectors/OutboundQueueWorkerTests.cs
+++ b/tests/Silverback.Integration.Tests/Messaging/Connectors/OutboundQueueWorkerTests.cs
@@ -46,7 +46,7 @@ public OutboundQueueWorkerTests()
var serviceProvider = services.BuildServiceProvider(new ServiceProviderOptions { ValidateScopes = true });
serviceProvider.GetRequiredService()
- .Add(new StaticOutboundRouter(TestProducerEndpoint.GetDefault()));
+ .Add(_ => new StaticOutboundRouter(TestProducerEndpoint.GetDefault()));
_broker = (TestBroker) serviceProvider.GetRequiredService();
_broker.Connect();
diff --git a/tests/Silverback.Integration.Tests/Messaging/HealthChecks/OutboundEndpointsHealthCheckServiceTests.cs b/tests/Silverback.Integration.Tests/Messaging/HealthChecks/OutboundEndpointsHealthCheckServiceTests.cs
index c529fea98..615ba661b 100644
--- a/tests/Silverback.Integration.Tests/Messaging/HealthChecks/OutboundEndpointsHealthCheckServiceTests.cs
+++ b/tests/Silverback.Integration.Tests/Messaging/HealthChecks/OutboundEndpointsHealthCheckServiceTests.cs
@@ -1,6 +1,7 @@
// Copyright (c) 2020 Sergio Aquilini
// This code is licensed under MIT license (see LICENSE file for details)
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
@@ -37,20 +38,20 @@ public async Task PingAllEndpoints_AllEndpointsWorking_EachEndpointIsPinged()
{
new OutboundRoute(
typeof(TestEventOne),
- new StaticOutboundRouter(new TestProducerEndpoint("endpoint1")),
+ _ => new StaticOutboundRouter(new TestProducerEndpoint("endpoint1")),
typeof(OutboundConnector)),
new OutboundRoute(
typeof(TestEventTwo),
- new StaticOutboundRouter(new TestProducerEndpoint("endpoint2")),
+ _ => new StaticOutboundRouter(new TestProducerEndpoint("endpoint2")),
typeof(OutboundConnector)),
new OutboundRoute(
typeof(TestEventThree),
- new StaticOutboundRouter(new TestProducerEndpoint("endpoint3")),
+ _ => new StaticOutboundRouter(new TestProducerEndpoint("endpoint3")),
typeof(OutboundConnector))
});
var service = new OutboundEndpointsHealthCheckService(configuration,
- new BrokerCollection(new[] { broker }));
+ new BrokerCollection(new[] { broker }), Substitute.For());
await service.PingAllEndpoints();
@@ -77,20 +78,20 @@ public async Task PingAllEndpoints_AllEndpointsWorking_ResultsAreAllSuccess()
{
new OutboundRoute(
typeof(TestEventOne),
- new StaticOutboundRouter(new TestProducerEndpoint("endpoint1")),
+ _ => new StaticOutboundRouter(new TestProducerEndpoint("endpoint1")),
typeof(OutboundConnector)),
new OutboundRoute(
typeof(TestEventTwo),
- new StaticOutboundRouter(new TestProducerEndpoint("endpoint2")),
+ _ => new StaticOutboundRouter(new TestProducerEndpoint("endpoint2")),
typeof(OutboundConnector)),
new OutboundRoute(
typeof(TestEventThree),
- new StaticOutboundRouter(new TestProducerEndpoint("endpoint3")),
+ _ => new StaticOutboundRouter(new TestProducerEndpoint("endpoint3")),
typeof(OutboundConnector))
});
var service = new OutboundEndpointsHealthCheckService(configuration,
- new BrokerCollection(new[] { broker }));
+ new BrokerCollection(new[] { broker }), Substitute.For());
var results = await service.PingAllEndpoints();
@@ -116,20 +117,20 @@ public async Task PingAllEndpoints_SomeEndpointNotWorking_FailureIsProperlyRepor
{
new OutboundRoute(
typeof(TestEventOne),
- new StaticOutboundRouter(new TestProducerEndpoint("endpoint1")),
+ _ => new StaticOutboundRouter(new TestProducerEndpoint("endpoint1")),
typeof(OutboundConnector)),
new OutboundRoute(
typeof(TestEventTwo),
- new StaticOutboundRouter(new TestProducerEndpoint("endpoint2")),
+ _ => new StaticOutboundRouter(new TestProducerEndpoint("endpoint2")),
typeof(OutboundConnector)),
new OutboundRoute(
typeof(TestEventThree),
- new StaticOutboundRouter(new TestProducerEndpoint("endpoint3")),
+ _ => new StaticOutboundRouter(new TestProducerEndpoint("endpoint3")),
typeof(OutboundConnector))
});
var service = new OutboundEndpointsHealthCheckService(configuration,
- new BrokerCollection(new[] { broker }));
+ new BrokerCollection(new[] { broker }), Substitute.For());
var results = (await service.PingAllEndpoints()).ToList();