Skip to content

Commit

Permalink
fix: Reworks TenantResolver
Browse files Browse the repository at this point in the history
  • Loading branch information
gshukov98 committed Jul 8, 2022
2 parents a775cc9 + 05c136b commit fbb61a3
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 6 deletions.
20 changes: 20 additions & 0 deletions src/Elders.Cronus/Exception/UnableToResolveTenantExeption.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;
using System.Runtime.Serialization;

namespace Elders.Cronus.AspNetCore.Exeptions
{
[Serializable]
// Important: This attribute is NOT inherited from Exception, and MUST be specified
// otherwise serialization will fail with a SerializationException stating that
// "Type X in Assembly Y is not marked as serializable."
public class UnableToResolveTenantException : Exception
{
public UnableToResolveTenantException() { }

public UnableToResolveTenantException(string message) : this(message, null) { }

public UnableToResolveTenantException(string message, Exception innerException) : base(message, innerException) { }

protected UnableToResolveTenantException(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
}
39 changes: 33 additions & 6 deletions src/Elders.Cronus/Multitenancy/ITenantResolver.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using Microsoft.Extensions.DependencyInjection;
using Elders.Cronus.AspNetCore.Exeptions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Reflection;

namespace Elders.Cronus.Multitenancy
Expand All @@ -12,18 +15,30 @@ public interface ITenantResolver

public interface ITenantResolver<in T>
{
/// <summary>
/// Resolves a teannt name from a specific source.
/// </summary>
/// <param name="source">The source from which the system will try to extract the tenant name.</param>
/// <returns>Returns the tenant name or empty string if the tenant resolving fails.</returns>
/// <remarks>
/// This method should never throw an exception. The system will try to resolve the tenant name
/// from several places based on the current execution chain. If the process still fails then
/// an exception will be thrown from the underlying execution.
/// </remarks>
string Resolve(T source);
}

public class TenantResolver : ITenantResolver
{
ConcurrentDictionary<Type, ResolverCache> resolvers = new ConcurrentDictionary<Type, ResolverCache>();

private readonly TenantsOptions tenants;
private readonly IServiceProvider serviceProvider;

public TenantResolver(IServiceProvider serviceProvider)
public TenantResolver(IServiceProvider serviceProvider, IOptions<TenantsOptions> tenantsOptions)
{
this.serviceProvider = serviceProvider;
this.tenants = tenantsOptions.Value;
}

public string Resolve(object source)
Expand All @@ -33,16 +48,28 @@ public string Resolve(object source)
ResolverCache resolverCache;
if (resolvers.TryGetValue(source.GetType(), out resolverCache) == false)
{
var tenantResolverType = typeof(ITenantResolver<>);
var tenantResolverTypeGeneric = tenantResolverType.MakeGenericType(source.GetType());
var resolver = serviceProvider.GetRequiredService(tenantResolverTypeGeneric);
Type tenantResolverType = typeof(ITenantResolver<>);
Type tenantResolverTypeGeneric = tenantResolverType.MakeGenericType(source.GetType());
object resolver = serviceProvider.GetRequiredService(tenantResolverTypeGeneric);
MethodInfo resolveMethod = tenantResolverTypeGeneric.GetMethod("Resolve");

resolverCache = new ResolverCache(resolver, resolveMethod);
resolvers.TryAdd(source.GetType(), resolverCache);
}

return resolverCache.GetTenantFrom(source);
string tenant = resolverCache.GetTenantFrom(source);

if (string.IsNullOrEmpty(tenant) == false)
{
return tenant;
}
else
{
if (tenants.Tenants.Count() == 1)
return tenants.Tenants.Single();
}

throw new UnableToResolveTenantException("Unable to resolve tenant.");
}

class ResolverCache
Expand Down

0 comments on commit fbb61a3

Please sign in to comment.