public void AddHeaderStrategy()
        {
            var services = new ServiceCollection();
            var builder  = new FinbuckleMultiTenantBuilder <TenantInfo>(services);

            builder.WithHeaderStrategy();
            var sp = services.BuildServiceProvider();

            var strategy = sp.GetRequiredService <IMultiTenantStrategy>();

            Assert.IsType <HeaderStrategy>(strategy);
        }
        public void AddDelegateStrategy()
        {
            var services = new ServiceCollection();
            var builder  = new FinbuckleMultiTenantBuilder <TenantInfo>(services);

            builder.WithDelegateStrategy(_ => Task.FromResult <string?>("Hi"));
            var sp = services.BuildServiceProvider();

            var strategy = sp.GetRequiredService <IMultiTenantStrategy>();

            Assert.IsType <DelegateStrategy>(strategy);
        }
コード例 #3
0
    public void AddRemoteAuthenticationServices()
    {
        var services = new ServiceCollection();
        var builder  = new FinbuckleMultiTenantBuilder(services);

        services.AddAuthentication();
        builder.WithRemoteAuthentication();
        var sp = services.BuildServiceProvider();

        var authService    = sp.GetRequiredService <IAuthenticationService>();        // Throw fails
        var schemeProvider = sp.GetRequiredService <IAuthenticationSchemeProvider>(); // Throw fails
    }
コード例 #4
0
    public void AddBasePathStrategy()
    {
        var services = new ServiceCollection();
        var builder  = new FinbuckleMultiTenantBuilder(services);

        builder.WithBasePathStrategy();
        var sp = services.BuildServiceProvider();

        var strategy = sp.GetRequiredService <IMultiTenantStrategy>();

        Assert.IsType <MultiTenantStrategyWrapper <BasePathStrategy> >(strategy);
    }
コード例 #5
0
    public void AddFallbackTenantIdentifier()
    {
        var services = new ServiceCollection();
        var builder  = new FinbuckleMultiTenantBuilder(services);

        builder.WithFallbackStrategy("test");
        var sp = services.BuildServiceProvider();

        var strategy = sp.GetRequiredService <FallbackStrategy>();

        Assert.Equal("test", strategy.identifier);
    }
コード例 #6
0
        public void AddEfCoreStoreWithExistingDbContext()
        {
            var services = new ServiceCollection();
            var builder  = new FinbuckleMultiTenantBuilder <TenantInfo>(services);

            services.AddDbContext <TestEfCoreStoreDbContext>(o => o.UseSqlite("DataSource=:memory:"));
            builder.WithStaticStrategy("initech").WithEFCoreStore <TestEfCoreStoreDbContext, TenantInfo>();
            var sp = services.BuildServiceProvider().CreateScope().ServiceProvider;

            var resolver = sp.GetRequiredService <IMultiTenantStore <TenantInfo> >();

            Assert.IsType <EFCoreStore <TestEfCoreStoreDbContext, TenantInfo> >(resolver);
        }
        public void AddHttpRemoteStoreAndHttpRemoteStoreClient()
        {
            var services = new ServiceCollection();
            var builder  = new FinbuckleMultiTenantBuilder <TenantInfo>(services);

            builder.WithHttpRemoteStore("http://example.com");
            var sp = services.BuildServiceProvider();

            sp.GetRequiredService <HttpRemoteStoreClient <TenantInfo> >();
            var store = sp.GetRequiredService <IMultiTenantStore <TenantInfo> >();

            Assert.IsType <HttpRemoteStore <TenantInfo> >(store);
        }
        public void AddDistributedCacheStoreWithSlidingExpiration()
        {
            var services = new ServiceCollection();

            services.AddDistributedMemoryCache();
            var builder = new FinbuckleMultiTenantBuilder <TenantInfo>(services);

            builder.WithDistributedCacheStore(TimeSpan.FromMinutes(5));
            var sp    = services.BuildServiceProvider();
            var store = sp.GetRequiredService <IMultiTenantStore <TenantInfo> >();

            Assert.IsType <DistributedCacheStore <TenantInfo> >(store);
        }
コード例 #9
0
    public void AddRouteStrategy()
    {
        var services = new ServiceCollection();
        var adcp     = new Mock <IActionDescriptorCollectionProvider>().Object;

        services.AddSingleton <IActionDescriptorCollectionProvider>(adcp);
        var builder = new FinbuckleMultiTenantBuilder(services);

        builder.WithRouteStrategy("routeParam", cr => cr.MapRoute("test", "test"));
        var sp = services.BuildServiceProvider();

        var strategy = sp.GetRequiredService <IMultiTenantStrategy>();

        Assert.IsType <MultiTenantStrategyWrapper <RouteStrategy> >(strategy);
    }
コード例 #10
0
    public void AddPerTenantOptions()
    {
        var services = new ServiceCollection();
        var accessor = new Mock <IMultiTenantContextAccessor <TenantInfo> >();

        accessor.Setup(a => a.MultiTenantContext).Returns((IMultiTenantContext <TenantInfo>)null);
        services.AddSingleton <IMultiTenantContextAccessor <TenantInfo> >(accessor.Object);
        var builder = new FinbuckleMultiTenantBuilder <TenantInfo>(services);

        // Note: using MultiTenantBuilderShould as our test options class.
        builder.WithPerTenantOptions <MultiTenantBuilderShould>((o, tc) => o.TestProperty = 1);
        var sp = services.BuildServiceProvider();

        var cache = sp.GetRequiredService <IOptionsMonitorCache <MultiTenantBuilderShould> >();
    }
    public void ThrowIfMissingIdOrIdentifierInTenantConfig(string jsonFile)
    {
        var configBuilder = new ConfigurationBuilder();

        configBuilder.AddJsonFile(jsonFile);
        var configuration = configBuilder.Build();

        var services = new ServiceCollection();
        var builder  = new FinbuckleMultiTenantBuilder(services);

        builder.WithInMemoryStore(o => configuration.GetSection("Finbuckle:MultiTenant:InMemoryStore").Bind(o));
        var sp = services.BuildServiceProvider();

        Assert.Throws <MultiTenantException>(() => sp.GetRequiredService <IMultiTenantStore>());
    }
コード例 #12
0
    public void AddHttpRemoteStoreWithHttpClientBuilders()
    {
        var services = new ServiceCollection();
        var builder  = new FinbuckleMultiTenantBuilder(services);
        var flag     = false;

        builder.WithHttpRemoteStore("http://example.com", b => flag = true);
        var sp = services.BuildServiceProvider();

        sp.GetRequiredService <HttpRemoteStoreClient>();
        var store = sp.GetRequiredService <IMultiTenantStore>();

        Assert.IsType <MultiTenantStoreWrapper <HttpRemoteStore> >(store);
        Assert.True(flag);
    }
コード例 #13
0
        public void AddPerTenantNamedOptions()
        {
            var services = new ServiceCollection();
            var accessor = new Mock <IMultiTenantContextAccessor <TenantInfo> >();

            accessor.Setup(a => a.MultiTenantContext).Returns((IMultiTenantContext <TenantInfo>?)null);
            services.AddSingleton(accessor.Object);
            var builder = new FinbuckleMultiTenantBuilder <TenantInfo>(services);

            // Note: using MultiTenantBuilderShould as our test options class.
            builder.WithPerTenantNamedOptions <MultiTenantBuilderShould>("a name", (o, _) => o.TestProperty = 1);
            var sp = services.BuildServiceProvider();

            sp.GetRequiredService <ITenantConfigureNamedOptions <MultiTenantBuilderShould, TenantInfo> >();
        }
        public void AddBasePathStrategyWithOptions()
        {
            var services = new ServiceCollection();
            var builder  = new FinbuckleMultiTenantBuilder <TenantInfo>(services);

            builder.WithBasePathStrategy(options => options.RebaseAspNetCorePathBase = true);
            var sp = services.BuildServiceProvider();

            var strategy = sp.GetRequiredService <IMultiTenantStrategy>();

            Assert.IsType <BasePathStrategy>(strategy);

            var options = sp.GetRequiredService <IOptions <BasePathStrategyOptions> >();

            Assert.True(options.Value.RebaseAspNetCorePathBase);
        }
コード例 #15
0
        private static FinbuckleMultiTenantBuilder <TenantInfo> WithMultiTenantStrategy(this FinbuckleMultiTenantBuilder <TenantInfo> builder)
        {
            // Build the intermediate service provider
            var defaultTenantConfig = _configuration.GetSection("DefaultTenant");

            return(builder
                   // A template pattern can be specified with the overloaded version. The default pattern is "__tenant__.*"
                   // For example, a request to "https://contoso.example.com/abc123" would use "contoso" as the identifier when resolving the tenant.
                   .WithHostStrategy()
                   // For example, a request to "https://www.example.com/contoso" would use "contoso" as the identifier when resolving the tenant.
                   .WithBasePathStrategy()
                   // For example, a request to "https://www.example.com/contoso/home/" and a route configuration of {__tenant__}/{controller=Home}/{action=Index} would use "contoso" as the identifier when resolving the tenant.
                   .WithRouteStrategy()
                   // If the called with e.g. "not_a_tenant.mysite.com" and the identifer "not_a_tenant"
                   // is not in the store, then the identifier of "DefaultTenant" will be used as a fallback.
                   // Make sure to include a multitenant store !
                   .WithStaticStrategy(defaultTenantConfig.GetValue <string>("Identifier")));
            // .WithRemoteAuthentication() for per-tenant remote authentication
        }
コード例 #16
0
 /// <Summary>
 /// Finbuckle.MultiTenant provides four basic multitenant stores :
 /// * InMemoryStore - a simple, thread safe in-memory implementation based on ConcurrentDictionary<string, object>.
 /// * ConfigurationStore - a read-only store that is back by app configuration (e.g. appsettings.json).
 /// * EFCoreStore - an Entity Framework Core based implementation to query tenant information from a database.
 /// ** HttpRemoteStore - a read-only store that sends the tenant identifier to an http(s) endpoint to get the tenant information.
 /// </Summary>
 private static FinbuckleMultiTenantBuilder <TenantInfo> WithMultiTenantStore(this FinbuckleMultiTenantBuilder <TenantInfo> builder)
 {
     // Register to use the database context and TTenantInfo types show above.
     return(builder.WithEFCoreStore <TenantStoreDbContext, TenantInfo>());
 }