Skip to content

Commit a26081c

Browse files
authoredDec 21, 2023
fix: OnTenantNotResolved not called correctly (#729)
fix issue with OnTenantNotResolved only firing if the store failed to find a match rather than either the strategy not finding an identifier or the store not finding a match. fixes #628
1 parent d7f08f9 commit a26081c

File tree

2 files changed

+90
-27
lines changed

2 files changed

+90
-27
lines changed
 

‎src/Finbuckle.MultiTenant/TenantResolver.cs

+27-27
Original file line numberDiff line numberDiff line change
@@ -38,47 +38,47 @@ public TenantResolver(IEnumerable<IMultiTenantStrategy> strategies, IEnumerable<
3838

3939
public async Task<IMultiTenantContext<T>?> ResolveAsync(object context)
4040
{
41-
IMultiTenantContext<T>? result = null;
42-
41+
string? identifier = null;
4342
foreach (var strategy in Strategies)
4443
{
4544
var _strategy = new MultiTenantStrategyWrapper(strategy, loggerFactory?.CreateLogger(strategy.GetType()) ?? NullLogger.Instance);
46-
var identifier = await _strategy.GetIdentifierAsync(context);
45+
identifier = await _strategy.GetIdentifierAsync(context);
4746

4847
if (options.CurrentValue.IgnoredIdentifiers.Contains(identifier, StringComparer.OrdinalIgnoreCase))
4948
{
5049
(loggerFactory?.CreateLogger(GetType()) ?? NullLogger.Instance).LogInformation("Ignored identifier: {Identifier}", identifier);
5150
identifier = null;
5251
}
52+
53+
if (identifier == null)
54+
continue;
5355

54-
if (identifier != null)
56+
foreach (var store in Stores)
5557
{
56-
foreach (var store in Stores)
57-
{
58-
var _store = new MultiTenantStoreWrapper<T>(store, loggerFactory?.CreateLogger(store.GetType()) ?? NullLogger.Instance);
59-
var tenantInfo = await _store.TryGetByIdentifierAsync(identifier);
60-
if (tenantInfo != null)
61-
{
62-
result = new MultiTenantContext<T>();
63-
result.StoreInfo = new StoreInfo<T> { Store = store, StoreType = store.GetType() };
64-
result.StrategyInfo = new StrategyInfo { Strategy = strategy, StrategyType = strategy.GetType() };
65-
result.TenantInfo = tenantInfo;
66-
67-
await options.CurrentValue.Events.OnTenantResolved(new TenantResolvedContext { Context =
68-
context, TenantInfo = tenantInfo, StrategyType = strategy.GetType(), StoreType = store.GetType()});
69-
70-
break;
71-
}
72-
}
58+
var _store = new MultiTenantStoreWrapper<T>(store, loggerFactory?.CreateLogger(store.GetType()) ?? NullLogger.Instance);
59+
var tenantInfo = await _store.TryGetByIdentifierAsync(identifier);
60+
if (tenantInfo == null)
61+
continue;
7362

74-
if (result != null)
75-
break;
76-
77-
await options.CurrentValue.Events.OnTenantNotResolved(new TenantNotResolvedContext { Context = context, Identifier = identifier });
63+
await options.CurrentValue.Events.OnTenantResolved(new TenantResolvedContext
64+
{
65+
Context = context,
66+
TenantInfo = tenantInfo,
67+
StrategyType = strategy.GetType(),
68+
StoreType = store.GetType()
69+
});
70+
71+
return new MultiTenantContext<T>
72+
{
73+
StoreInfo = new StoreInfo<T> { Store = store, StoreType = store.GetType() },
74+
StrategyInfo = new StrategyInfo { Strategy = strategy, StrategyType = strategy.GetType() },
75+
TenantInfo = tenantInfo
76+
};
7877
}
7978
}
80-
81-
return result;
79+
80+
await options.CurrentValue.Events.OnTenantNotResolved(new TenantNotResolvedContext { Context = context, Identifier = identifier });
81+
return null;
8282
}
8383

8484
// TODO move this to the base interface?

‎test/Finbuckle.MultiTenant.Test/TenantResolverShould.cs

+63
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using Finbuckle.MultiTenant.Strategies;
99
using Microsoft.Extensions.Configuration;
1010
using Microsoft.Extensions.DependencyInjection;
11+
using System.Collections.Generic;
1112
using Xunit;
1213

1314
namespace Finbuckle.MultiTenant.Test
@@ -213,5 +214,67 @@ public void ReturnNullIfNoStoreSuccess()
213214

214215
Assert.Null(result);
215216
}
217+
218+
[Fact]
219+
public void CallOnTenantResolvedEventIfSuccess()
220+
{
221+
TenantResolvedContext? resolvedContext = null;
222+
223+
var configuration = new ConfigurationBuilder()
224+
.AddJsonFile("ConfigurationStoreTestSettings.json")
225+
.Build();
226+
227+
var services = new ServiceCollection();
228+
services.AddSingleton<IConfiguration>(configuration);
229+
services.Configure<MultiTenantOptions>(options => options.Events.OnTenantResolved = context => Task.FromResult(resolvedContext = context));
230+
services.AddMultiTenant<TenantInfo>()
231+
.WithDelegateStrategy(_ => Task.FromResult<string?>("not-found"))
232+
.WithStaticStrategy("initech")
233+
.WithConfigurationStore();
234+
var sp = services.BuildServiceProvider();
235+
var resolver = sp.GetRequiredService<ITenantResolver<TenantInfo>>();
236+
237+
_ = resolver.ResolveAsync(new object()).Result;
238+
239+
Assert.NotNull(resolvedContext);
240+
Assert.Equal("initech", resolvedContext.TenantInfo!.Identifier);
241+
Assert.Equal(typeof(StaticStrategy), resolvedContext.StrategyType);
242+
Assert.Equal(typeof(ConfigurationStore<TenantInfo>), resolvedContext.StoreType);
243+
}
244+
245+
[Fact]
246+
public void CallOnTenantNotResolvedEventIfNoStrategySuccess()
247+
{
248+
TenantNotResolvedContext? notResolvedContext = null;
249+
250+
var services = new ServiceCollection();
251+
services.Configure<MultiTenantOptions>(options => options.Events.OnTenantNotResolved = context => Task.FromResult(notResolvedContext = context));
252+
services
253+
.AddMultiTenant<TenantInfo>()
254+
.WithDelegateStrategy(_ => Task.FromResult<string?>(null!));
255+
var sp = services.BuildServiceProvider();
256+
var resolver = sp.GetRequiredService<ITenantResolver<TenantInfo>>();
257+
258+
_ = resolver.ResolveAsync(new object()).Result;
259+
260+
Assert.NotNull(notResolvedContext);
261+
}
262+
263+
[Fact]
264+
public void CallOnTenantNotResolvedEventIfNoStoreSuccess()
265+
{
266+
TenantNotResolvedContext? notResolvedContext = null;
267+
var services = new ServiceCollection();
268+
services.Configure<MultiTenantOptions>(options => options.Events.OnTenantNotResolved = context => Task.FromResult(notResolvedContext = context));
269+
services.AddMultiTenant<TenantInfo>()
270+
.WithStaticStrategy("not-found")
271+
.WithInMemoryStore();
272+
var sp = services.BuildServiceProvider();
273+
var resolver = sp.GetRequiredService<ITenantResolver<TenantInfo>>();
274+
275+
_ = resolver.ResolveAsync(new object()).Result;
276+
277+
Assert.NotNull(notResolvedContext);
278+
}
216279
}
217280
}

0 commit comments

Comments
 (0)
Please sign in to comment.