Setup authentication with multitenant (separate databases)

I’m using this filter to set the current tenantID

GlobalRequestFilters.Add((req, res, dto) => {
	string tenant = GetTenantFromRequest(req);
	req.Items[MultiTenantDbFactory.TenantId] = tenant;
	req.Items[Keywords.DbInfo] = new ConnectionInfo { NamedConnection = tenant };
});

and registering a MultiTenantDbFactory

OrmLiteConnectionFactory factory = new OrmLiteConnectionFactory(Program.ConnectionString, PostgreSqlDialect.Provider, true);
factory.RegisterConnection("EL", "....", PostgreSqlDialect.Provider);
container.Register<IDbConnectionFactory>(new MultiTenantDbFactory(factory));

See MultiTenantDbFactory

But the OrmLiteAuthRepositoryMultitenancy is not accepting a OrmLiteConnectionFactory instance.

In my opinion there are too many ways to get a IDbConnection instance (scoped to CurrentRequest). Why not route every request for IDbConnection always to AppHost.GetDbConnection(…) (via a simple ConnectionInfo instance)

Thanks

See the docs on Multitenancy for built-in support available and how to register the Multitenancy RDBMS AuthProvider.

You should only adopt one of the strategies, i.e. if you’re going to set req.Items[Keywords.DbInfo] in a Request Filter that’s all you need to do, the base.Db in your Service fetches the DB Connection from AppHost.GetDbConnection() configured to the specified connection.

Anywhere else you need a DB connection you’ll need to resolve from HostContext.AppHost.GetDbConnection(IRequest) which is what everywhere else in ServiceStack that uses a DB connection resolves it from, i.e. AutoQuery, Razor Views, Sharp Pages, MVC ServiceStackController, etc.

Thanks. But when/where is the IDbConnection instance disposed when you AppHost.GetAuthRepository(req) is called?

using:

public override IAuthRepository GetAuthRepository(IRequest req = null)
{
    return req != null
        ? new OrmLiteAuthRepositoryMultitenancy(GetDbConnection(req)) //At Runtime
        : TryResolve<IAuthRepository>();                              //On Startup
}

It’s disposed of after use, when retrieving it from AppHost.GetAuthRepository() the repository should be accessed like:

var authRepo = HostContext.AppHost.GetAuthRepository(req);
using (authRepo as IDisposable)
{
}

You can use and access base.AuthRepository like normal in a Service, it’s disposed of after the Service is executed.

Why isn’t the idbconnection registered as a request scoped instance and disposed at one place,via the ioc-container? (With additional benefit of having a singe instance for each request)

There is no benefit to using Request Scope, which I never use anywhere, for pooled resources it keeps them open for longer, when they should be disposed/released immediately after usage. Whenever it’s ThreadSafe, dependencies should be registered as singleton to minimize allocations.

But not for an IDbConnection, Connecting/Disconnecting takes more time. Is there a way to work around your personal preference and always a single request scoped IDbConnection?

No it doesn’t, db connections are pooled by default, where disposing a connection releases it back to the pool. You can override AppHost.GetDbConnection() in your AppHost and implement it how you like.