Skip to content

Commit

Permalink
Add support for transient and scoped IOutboundRouter
Browse files Browse the repository at this point in the history
  • Loading branch information
BEagle1984 committed Jul 8, 2020
1 parent d861da3 commit 74cf14a
Show file tree
Hide file tree
Showing 18 changed files with 323 additions and 79 deletions.
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<License>MIT</License>
<Copyright>Copyright (c) 2020 Sergio Aquilini</Copyright>
<VersionSuffix></VersionSuffix>
<BaseVersion>2.1.2$(VersionSuffix)</BaseVersion>
<BaseVersion>2.2.0$(VersionSuffix)</BaseVersion>
<ProjectUrl>https://beagle1984.github.io/silverback/</ProjectUrl>
<RepositoryUrl>https://github.com/BEagle1984/silverback/</RepositoryUrl>
<RepositoryType>git</RepositoryType>
Expand Down
5 changes: 5 additions & 0 deletions docs/_docs/0-introduction/003-releases.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 0 additions & 4 deletions docs/_docs/2-configuration/202-outbound.md
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,3 @@ public class Startup
}
{% endhighlight %}
</figure>

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}

Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ protected override void ConfigureServices(IServiceCollection services) => servic
.AddSilverback()
.UseModel()
.WithConnectionToMessageBroker(options => options.AddKafka())
.AddSingletonOutboundRouter<PrioritizedOutboundRouter>();
.AddScopedOutboundRouter<PrioritizedOutboundRouter>();

protected override void Configure(BusConfigurator configurator, IServiceProvider serviceProvider) =>
configurator.Connect(endpoints => endpoints
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ protected override async Task Execute(IServiceProvider serviceProvider)

var result = await new OutboundEndpointsHealthCheckService(
serviceProvider.GetRequiredService<IOutboundRoutingConfiguration>(),
serviceProvider.GetRequiredService<IBrokerCollection>()).PingAllEndpoints();
serviceProvider.GetRequiredService<IBrokerCollection>(),
serviceProvider).PingAllEndpoints();

Console.ForegroundColor = Constants.PrimaryColor;
Console.WriteLine(JsonConvert.SerializeObject(result, Formatting.Indented));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ public static IBrokerCollection Connect(
var endpointsConfigurationBuilder = new EndpointsConfigurationBuilder(
configurator.ServiceProvider.GetRequiredService<IOutboundRoutingConfiguration>(),
configurator.ServiceProvider.GetRequiredService<IEnumerable<IInboundConnector>>(),
configurator.ServiceProvider.GetRequiredService<ErrorPolicyBuilder>(),
configurator.ServiceProvider);
configurator.ServiceProvider.GetRequiredService<ErrorPolicyBuilder>());
endpointsConfigurationAction?.Invoke(endpointsConfigurationBuilder);

configurator.ServiceProvider.GetServices<IEndpointsConfigurator>().ForEach(c =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,15 @@ public class EndpointsConfigurationBuilder : IEndpointsConfigurationBuilder
private readonly IOutboundRoutingConfiguration _outboundRoutingConfiguration;
private readonly IReadOnlyCollection<IInboundConnector> _inboundConnectors;
private readonly ErrorPolicyBuilder _errorPolicyBuilder;
private readonly IServiceProvider _serviceProvider;

public EndpointsConfigurationBuilder(
IOutboundRoutingConfiguration outboundRoutingConfiguration,
IEnumerable<IInboundConnector> inboundConnectors,
ErrorPolicyBuilder errorPolicyBuilder,
IServiceProvider serviceProvider)
ErrorPolicyBuilder errorPolicyBuilder)
{
_outboundRoutingConfiguration = outboundRoutingConfiguration;
_inboundConnectors = inboundConnectors.ToList();
_errorPolicyBuilder = errorPolicyBuilder;
_serviceProvider = serviceProvider;
}

public IEndpointsConfigurationBuilder AddOutbound<TMessage, TConnector>(IProducerEndpoint endpoint)
Expand Down Expand Up @@ -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;
}

Expand All @@ -95,7 +93,7 @@ public IEndpointsConfigurationBuilder AddOutbound(
IOutboundRouter router,
Type outboundConnectorType)
{
_outboundRoutingConfiguration.Add(messageType, router, outboundConnectorType);
_outboundRoutingConfiguration.Add(messageType, _ => router, outboundConnectorType);
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ public static IServiceCollection AddEndpointsConfigurator(
/// <returns>A reference to this instance after the operation has completed.</returns>
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);

Expand Down Expand Up @@ -106,7 +107,8 @@ public static IServiceCollection AddSingletonBrokerBehavior(
this IServiceCollection services,
Func<IServiceProvider, IBrokerBehavior> implementationFactory)
{
if (implementationFactory == null) throw new ArgumentNullException(nameof(implementationFactory));
if (implementationFactory == null)
throw new ArgumentNullException(nameof(implementationFactory));

services.AddSingleton(typeof(IBrokerBehavior), implementationFactory);

Expand All @@ -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);

Expand All @@ -137,6 +140,128 @@ public static IServiceCollection AddSingletonBrokerBehavior(

#endregion

#region AddTransientOutboundRouter

/// <summary>
/// Adds a transient outbound router of the type specified in <paramref name="routerType" /> to the
/// specified <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" />.
/// </summary>
/// <param name="services">
/// The <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" /> to add the
/// service to.
/// </param>
/// <param name="routerType">The type of the outbound router to register and the implementation to use.</param>
/// <returns>A reference to this instance after the operation has completed.</returns>
public static IServiceCollection AddTransientOutboundRouter(this IServiceCollection services, Type routerType)
{
if (routerType == null)
throw new ArgumentNullException(nameof(routerType));

services.AddTransient(routerType);

return services;
}

/// <summary>
/// Adds a transient outbound router of the type specified in <typeparamref name="TRouter" /> to the
/// specified <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" />.
/// </summary>
/// <typeparam name="TRouter">The type of the outbound router to add.</typeparam>
/// <param name="services">
/// The <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" /> to add the
/// service to.
/// </param>
/// <returns>A reference to this instance after the operation has completed.</returns>
public static IServiceCollection AddTransientOutboundRouter<TRouter>(this IServiceCollection services)
where TRouter : class, IOutboundRouter =>
AddTransientOutboundRouter(services, typeof(TRouter));

/// <summary>
/// Adds a transient outbound router with a
/// factory specified in <paramref name="implementationFactory" /> to the
/// specified <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" />.
/// </summary>
/// <param name="services">
/// The <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" /> to add the
/// service to.
/// </param>
/// <param name="implementationFactory">The factory that creates the service.</param>
/// <returns>A reference to this instance after the operation has completed.</returns>
public static IServiceCollection AddTransientOutboundRouter(
this IServiceCollection services,
Func<IServiceProvider, IOutboundRouter> implementationFactory)
{
if (implementationFactory == null)
throw new ArgumentNullException(nameof(implementationFactory));

services.AddTransient(implementationFactory);

return services;
}

#endregion

#region AddScopedOutboundRouter

/// <summary>
/// Adds a scoped outbound router of the type specified in <paramref name="routerType" /> to the
/// specified <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" />.
/// </summary>
/// <param name="services">
/// The <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" /> to add the
/// service to.
/// </param>
/// <param name="routerType">The type of the outbound router to register and the implementation to use.</param>
/// <returns>A reference to this instance after the operation has completed.</returns>
public static IServiceCollection AddScopedOutboundRouter(this IServiceCollection services, Type routerType)
{
if (routerType == null)
throw new ArgumentNullException(nameof(routerType));

services.AddScoped(routerType);

return services;
}

/// <summary>
/// Adds a scoped outbound router of the type specified in <typeparamref name="TRouter" /> to the
/// specified <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" />.
/// </summary>
/// <typeparam name="TRouter">The type of the outbound router to add.</typeparam>
/// <param name="services">
/// The <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" /> to add the
/// service to.
/// </param>
/// <returns>A reference to this instance after the operation has completed.</returns>
public static IServiceCollection AddScopedOutboundRouter<TRouter>(this IServiceCollection services)
where TRouter : class, IOutboundRouter =>
AddScopedOutboundRouter(services, typeof(TRouter));

/// <summary>
/// Adds a scoped outbound router with a
/// factory specified in <paramref name="implementationFactory" /> to the
/// specified <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" />.
/// </summary>
/// <param name="services">
/// The <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" /> to add the
/// service to.
/// </param>
/// <param name="implementationFactory">The factory that creates the service.</param>
/// <returns>A reference to this instance after the operation has completed.</returns>
public static IServiceCollection AddScopedOutboundRouter(
this IServiceCollection services,
Func<IServiceProvider, IOutboundRouter> implementationFactory)
{
if (implementationFactory == null)
throw new ArgumentNullException(nameof(implementationFactory));

services.AddScoped(implementationFactory);

return services;
}

#endregion

#region AddSingletonOutboundRouter

/// <summary>
Expand All @@ -151,7 +276,8 @@ public static IServiceCollection AddSingletonBrokerBehavior(
/// <returns>A reference to this instance after the operation has completed.</returns>
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);

Expand Down Expand Up @@ -187,7 +313,8 @@ public static IServiceCollection AddSingletonOutboundRouter(
this IServiceCollection services,
Func<IServiceProvider, IOutboundRouter> implementationFactory)
{
if (implementationFactory == null) throw new ArgumentNullException(nameof(implementationFactory));
if (implementationFactory == null)
throw new ArgumentNullException(nameof(implementationFactory));

services.AddSingleton(implementationFactory);

Expand All @@ -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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,100 @@ public static ISilverbackBuilder AddSingletonBrokerBehavior(

#endregion

#region AddTransientOutboundRouter

/// <summary>
/// Adds a transient outbound router of the type specified in <paramref name="routerType" /> to the
/// <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" />.
/// </summary>
/// <param name="builder"></param>
/// <param name="routerType">The type of the outbound router to register and the implementation to use.</param>
/// <returns>A reference to this instance after the operation has completed.</returns>
public static ISilverbackBuilder AddTransientOutboundRouter(this ISilverbackBuilder builder, Type routerType)
{
builder.Services.AddTransientOutboundRouter(routerType);
return builder;
}

/// <summary>
/// Adds a transient outbound router of the type specified in <typeparamref name="TRouter" /> to the
/// <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" />.
/// </summary>
/// <typeparam name="TRouter">The type of the outbound router to add.</typeparam>
/// <param name="builder"></param>
/// <returns>A reference to this instance after the operation has completed.</returns>
public static ISilverbackBuilder AddTransientOutboundRouter<TRouter>(this ISilverbackBuilder builder)
where TRouter : class, IOutboundRouter
{
builder.Services.AddTransientOutboundRouter<TRouter>();
return builder;
}

/// <summary>
/// Adds a transient outbound router with a
/// factory specified in <paramref name="implementationFactory" /> to the
/// <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" />.
/// </summary>
/// <param name="builder"></param>
/// <param name="implementationFactory">The factory that creates the service.</param>
/// <returns>A reference to this instance after the operation has completed.</returns>
public static ISilverbackBuilder AddTransientOutboundRouter(
this ISilverbackBuilder builder,
Func<IServiceProvider, IOutboundRouter> implementationFactory)
{
builder.Services.AddTransientOutboundRouter(implementationFactory);
return builder;
}

#endregion

#region AddScopedOutboundRouter

/// <summary>
/// Adds a scoped outbound router of the type specified in <paramref name="routerType" /> to the
/// <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" />.
/// </summary>
/// <param name="builder"></param>
/// <param name="routerType">The type of the outbound router to register and the implementation to use.</param>
/// <returns>A reference to this instance after the operation has completed.</returns>
public static ISilverbackBuilder AddScopedOutboundRouter(this ISilverbackBuilder builder, Type routerType)
{
builder.Services.AddScopedOutboundRouter(routerType);
return builder;
}

/// <summary>
/// Adds a scoped outbound router of the type specified in <typeparamref name="TRouter" /> to the
/// <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" />.
/// </summary>
/// <typeparam name="TRouter">The type of the outbound router to add.</typeparam>
/// <param name="builder"></param>
/// <returns>A reference to this instance after the operation has completed.</returns>
public static ISilverbackBuilder AddScopedOutboundRouter<TRouter>(this ISilverbackBuilder builder)
where TRouter : class, IOutboundRouter
{
builder.Services.AddScopedOutboundRouter<TRouter>();
return builder;
}

/// <summary>
/// Adds a scoped outbound router with a
/// factory specified in <paramref name="implementationFactory" /> to the
/// <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" />.
/// </summary>
/// <param name="builder"></param>
/// <param name="implementationFactory">The factory that creates the service.</param>
/// <returns>A reference to this instance after the operation has completed.</returns>
public static ISilverbackBuilder AddScopedOutboundRouter(
this ISilverbackBuilder builder,
Func<IServiceProvider, IOutboundRouter> implementationFactory)
{
builder.Services.AddScopedOutboundRouter(implementationFactory);
return builder;
}

#endregion

#region AddSingletonOutboundRouter

/// <summary>
Expand Down
Loading

0 comments on commit 74cf14a

Please sign in to comment.