如何在 ServiceStack.net 第 2 部分中使用 Funq 注册多个 IDbConnectionFactory 实例 [英] How to register multiple IDbConnectionFactory instances using Funq in ServiceStack.net part 2

查看:43
本文介绍了如何在 ServiceStack.net 第 2 部分中使用 Funq 注册多个 IDbConnectionFactory 实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

ServiceStack 已经交付了我抛出的所有内容,除了 SAAS(多租户)用例,其中单个 API 实例使用多个相同架构的数据库,每个租户一个.由于法律原因,这些数据库需要存放在不同的实例中.

ServiceStack has delivered on EVERYTHING I've thrown at it, except the SAAS (Multi-tenant) use case where single API instance is using several databases of the same schema, one per tenant. These databases, because of legal reasons need to be housed in separate instances.

所以,我的问题是,是否可以根据过滤器的元数据更改每个请求的连接?

So, my question is this, "Is it possible to change the connection per Request based on meta from a filter?

我的问题有点类似于这个一个,但增加了每个数据库都相同的扭曲.

My question is somewhat similar to this one, but with the added twist that each database is the same.

谢谢,斯蒂芬

如果我没记错的话,我认为 mythz 和我之前讨论过这个问题并发现即使我们能够改变 ADO 连接,IAuthRepository 也会被破坏.所以是不可行的.

If memory serves me correctly I think mythz and I have discussed this before and found that even if we were able to get the ADO connection to change, the IAuthRepository is then broken. So it's not feasible.

推荐答案

我添加了一个示例 多租户测试 显示了我的首选方法,我将使用自定义 IDbConnectionFactory 包装器,以便我对 Db 有更好的可见性和控制正在创建连接,即:

I've added an example Multi Tenant test showing my preferred approach where I would use a custom IDbConnectionFactory wrapper so I have better visibility and control of the Db Connections being created, i.e:

public class MultiTenantDbFactory : IDbConnectionFactory
{
    private readonly IDbConnectionFactory dbFactory;

    public MultiTenantDbFactory(IDbConnectionFactory dbFactory)
    {
        this.dbFactory = dbFactory;
    }

    public IDbConnection OpenDbConnection()
    {
        var tenantId = RequestContext.Instance.Items["TenantId"] as string;
        return tenantId != null
            ? dbFactory.OpenDbConnectionString(GetConnectionString(tenantId))
            : dbFactory.OpenDbConnection();
    }

    public IDbConnection CreateDbConnection()
    {
        return dbFactory.CreateDbConnection();
    }
}

我也更喜欢使用 ma​​ster dbFactory 单例实例作为非租户请求的默认值,同时指定要使用的方言提供程序:

I'll also prefer to have a master dbFactory singleton instance to use as a default for non-tenant requests which also specifies which Dialect Provider to use:

var dbFactory = new OrmLiteConnectionFactory(
    AppSettings.GetString("MasterDb"), SqlServerDialect.Provider);

container.Register<IDbConnectionFactory>(c =>
    new MultiTenantDbFactory(dbFactory));

为了表明服务是特定于租户的,我将创建一个自定义界面:

To indicate that a Service is tenant-specific, I'll just create a custom interface:

public interface IForTenant
{
    string TenantId { get; }
}

哪些请求 DTO 可以实施以表明它们是特定于租户的请求,即:

Which Request DTO's can implement to indicate they're tenant-specific requests, i.e:

public class GetTenant : IForTenant, IReturn<GetTenantResponse>
{
    public string TenantId { get; set; }
}

可以在ServiceStack 的请求管道中轻松检测到,就像全局请求过滤器拉出请求的租户并将其添加到RequestContext,例如:

Which can be easily detected throughout ServiceStack's Request pipeline like a Global Request Filter to pull out what tenant the request is for and add it to the RequestContext, e.g:

GlobalRequestFilters.Add((req, res, dto) =>
{
    var forTennant = dto as IForTenant;
    if (forTennant != null)
        RequestContext.Instance.Items.Add("TenantId", forTennant.TenantId);
});

MultiTenantDbFactory 然后可以读回它并打开到所需租户的数据库连接:

The MultiTenantDbFactory can then read this back and open the Db Connection to the desired tenant:

var tenantId = RequestContext.Instance.Items["TenantId"] as string;
return new OrmLiteConnectionFactory(GetConnectionStringFor(tenantId))
    .OpenDbConnection()

每当任何人访问其服务或依赖项中的 base.Db 时都会使用它.

Which will be used whenever anyone accesses base.Db in their services or dependencies.

这篇关于如何在 ServiceStack.net 第 2 部分中使用 Funq 注册多个 IDbConnectionFactory 实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆