Skip to content

Commit

Permalink
Feature/refactor injecting tenant service (#65)
Browse files Browse the repository at this point in the history
* moved AddTenantIdentificationStrategy into a builder

* added "return this;"
  • Loading branch information
dragos-rosca authored Mar 5, 2020
1 parent bcfdb8a commit 0d1bd48
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 123 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public static class DependencyInjectionExtensions
public static IServiceCollection AddDefaultHttpTenantIdentification(this IServiceCollection services)
{

services.AddTenantIdentification()
services.AddTenantService()
.AddTenantIdentificationStrategy<IdTenantIdentifier>(builder => builder
.AddTenantTokenResolver<TenantIdHeaderHttpTokenResolver>(DefaultTenantHttpHeaderName)
.AddTenantTokenResolver<QueryStringTenantIdTokenResolver>(DefaultTenantQueryStringParamName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public static class DependencyInjectionExtensions
public static IServiceCollection AddDefaultMessagingTenantIdentification(this IServiceCollection services)
{

services.AddTenantIdentification()
services.AddTenantService()
.AddTenantIdentificationStrategy<IdTenantIdentifier>(builder => builder
.AddTenantTokenResolver<TenantIdHeaderMessagingTokenResolver>(MessagingHeaders.TenantId));

Expand Down
Original file line number Diff line number Diff line change
@@ -1,110 +1,13 @@
using Microsoft.Extensions.DependencyInjection;
using NBB.MultiTenancy.Abstractions.Services;
using NBB.MultiTenancy.Identification.Identifiers;
using NBB.MultiTenancy.Identification.Resolvers;
using NBB.MultiTenancy.Identification.Services;
using System;
using System.Linq;
using Microsoft.Extensions.DependencyInjection.Extensions;


namespace NBB.MultiTenancy.Identification.Extensions
{
public static class DependencyInjectionExtensions
{
public static IServiceCollection AddTenantIdentification(this IServiceCollection services)
public static TenantServiceBuilder AddTenantService(this IServiceCollection services)
{
services.TryAddSingleton<ITenantService, TenantService>();
return services;
return new TenantServiceBuilder(services);
}

public static void AddTenantIdentificationStrategy<TTenantIdentifier>(this IServiceCollection service, params Type[] resolverTypes)
where TTenantIdentifier : class, ITenantIdentifier
{
service.AddTenantIdentificationStrategy(ImplementationFactory<TTenantIdentifier>, resolverTypes);
}

public static void AddTenantIdentificationStrategy(this IServiceCollection service, ITenantIdentifier identifier, params Type[] resolverTypes)
{
if (identifier == null)
{
throw new ArgumentNullException(nameof(identifier));
}

service.AddTenantIdentificationStrategy(ImplementationFactory(identifier), resolverTypes);
}

public static void AddTenantIdentificationStrategy(this IServiceCollection service, Func<IServiceProvider, ITenantIdentifier> implementationFactory, params Type[] resolverTypes)
{
if (implementationFactory == null)
{
throw new ArgumentNullException(nameof(implementationFactory));
}

if (resolverTypes == null)
{
throw new ArgumentNullException(nameof(resolverTypes));
}

var resolverInterfaceType = typeof(ITenantTokenResolver);
if (!resolverTypes.Any() || resolverTypes.Any(rt => !resolverInterfaceType.IsAssignableFrom(rt)))
{
throw new ArgumentException(nameof(resolverTypes));
}

service.AddSingleton(sp =>
{
var identifier = implementationFactory(sp);
var resolvers = resolverTypes.Select(resolverType => (ITenantTokenResolver)ActivatorUtilities.CreateInstance(sp, resolverType));

return new TenantIdentificationStrategy(resolvers, identifier);
});
}

public static void AddTenantIdentificationStrategy<TTenantIdentifier>(this IServiceCollection service, Action<TenantTokenResolverConfiguration> builder)
where TTenantIdentifier : class, ITenantIdentifier
{
service.AddTenantIdentificationStrategy(ImplementationFactory<TTenantIdentifier>, builder);
}

public static void AddTenantIdentificationStrategy(this IServiceCollection service, ITenantIdentifier identifier, Action<TenantTokenResolverConfiguration> builder)
{
if (identifier == null)
{
throw new ArgumentNullException(nameof(identifier));
}

service.AddTenantIdentificationStrategy(ImplementationFactory(identifier), builder);
}

public static void AddTenantIdentificationStrategy(this IServiceCollection service, Func<IServiceProvider, ITenantIdentifier> implementationFactory, Action<TenantTokenResolverConfiguration> builder)
{
if (implementationFactory == null)
{
throw new ArgumentNullException(nameof(implementationFactory));
}

if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}

var config = new TenantTokenResolverConfiguration();
builder.Invoke(config);

service.AddSingleton(sp =>
{
var identifier = implementationFactory(sp);
var resolvers = config.GetTenantTokenResolvers(sp);

return new TenantIdentificationStrategy(resolvers, identifier);
});
}

private static TTenantIdentifier ImplementationFactory<TTenantIdentifier>(IServiceProvider serviceProvider) where TTenantIdentifier : class, ITenantIdentifier
=> ActivatorUtilities.CreateInstance<TTenantIdentifier>(serviceProvider);

private static Func<IServiceProvider, TTenantIdentifier> ImplementationFactory<TTenantIdentifier>(TTenantIdentifier identifier) where TTenantIdentifier : class, ITenantIdentifier
=> _ => identifier;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using NBB.MultiTenancy.Abstractions.Services;
using NBB.MultiTenancy.Identification.Identifiers;
using NBB.MultiTenancy.Identification.Resolvers;
using NBB.MultiTenancy.Identification.Services;
using System;
using System.Linq;

namespace NBB.MultiTenancy.Identification.Extensions
{
public class TenantServiceBuilder
{
private readonly IServiceCollection _serviceCollector;

public TenantServiceBuilder(IServiceCollection serviceCollector)
{
_serviceCollector = serviceCollector;
_serviceCollector.TryAddSingleton<ITenantService, TenantService>();
}

public TenantServiceBuilder AddTenantIdentificationStrategy<TTenantIdentifier>(params Type[] resolverTypes)
where TTenantIdentifier : class, ITenantIdentifier
{
return AddTenantIdentificationStrategy(ImplementationFactory<TTenantIdentifier>, resolverTypes);
}

public TenantServiceBuilder AddTenantIdentificationStrategy(ITenantIdentifier identifier, params Type[] resolverTypes)
{
if (identifier == null)
{
throw new ArgumentNullException(nameof(identifier));
}

return AddTenantIdentificationStrategy(ImplementationFactory(identifier), resolverTypes);
}

public TenantServiceBuilder AddTenantIdentificationStrategy(Func<IServiceProvider, ITenantIdentifier> implementationFactory, params Type[] resolverTypes)
{
if (implementationFactory == null)
{
throw new ArgumentNullException(nameof(implementationFactory));
}

if (resolverTypes == null)
{
throw new ArgumentNullException(nameof(resolverTypes));
}

var resolverInterfaceType = typeof(ITenantTokenResolver);
if (!resolverTypes.Any() || resolverTypes.Any(rt => !resolverInterfaceType.IsAssignableFrom(rt)))
{
throw new ArgumentException(nameof(resolverTypes));
}

_serviceCollector.AddSingleton(sp =>
{
var identifier = implementationFactory(sp);
var resolvers = resolverTypes.Select(resolverType => (ITenantTokenResolver)ActivatorUtilities.CreateInstance(sp, resolverType));

return new TenantIdentificationStrategy(resolvers, identifier);
});

return this;
}

public TenantServiceBuilder AddTenantIdentificationStrategy<TTenantIdentifier>(Action<TenantTokenResolverConfiguration> builder)
where TTenantIdentifier : class, ITenantIdentifier
{
return AddTenantIdentificationStrategy(ImplementationFactory<TTenantIdentifier>, builder);
}

public TenantServiceBuilder AddTenantIdentificationStrategy(ITenantIdentifier identifier, Action<TenantTokenResolverConfiguration> builder)
{
if (identifier == null)
{
throw new ArgumentNullException(nameof(identifier));
}

return AddTenantIdentificationStrategy(ImplementationFactory(identifier), builder);
}

public TenantServiceBuilder AddTenantIdentificationStrategy(Func<IServiceProvider, ITenantIdentifier> implementationFactory, Action<TenantTokenResolverConfiguration> builder)
{
if (implementationFactory == null)
{
throw new ArgumentNullException(nameof(implementationFactory));
}

if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}

var config = new TenantTokenResolverConfiguration();
builder.Invoke(config);

_serviceCollector.AddSingleton(sp =>
{
var identifier = implementationFactory(sp);
var resolvers = config.GetTenantTokenResolvers(sp);

return new TenantIdentificationStrategy(resolvers, identifier);
});

return this;
}

private static TTenantIdentifier ImplementationFactory<TTenantIdentifier>(IServiceProvider serviceProvider) where TTenantIdentifier : class, ITenantIdentifier
=> ActivatorUtilities.CreateInstance<TTenantIdentifier>(serviceProvider);

private static Func<IServiceProvider, TTenantIdentifier> ImplementationFactory<TTenantIdentifier>(TTenantIdentifier identifier) where TTenantIdentifier : class, ITenantIdentifier
=> _ => identifier;
}
}
Loading

0 comments on commit 0d1bd48

Please sign in to comment.