Open Closed

Create custom ConnectionStringResolver for changing connectionString of second DBConext. #453


User avatar
0
joe@tronactive.com created
  • ABP Framework version: v3.1
  • UI type: Angular
  • Tiered (MVC) or Identity Server Seperated (Angular): Tiered Entity Framework SQL Server

I have 3 DB contexts, my main one for the ABP API database, two others that connect to two DBs that we already had and all works just fine.

We have one database that has Customer table in it and a Connection table. The Connection table holds DB connections for each customers. This is NOT the main ABP database. But what I want to do is split out Customer specific databses similar to how tenant specific DBs are done in ABP. I want to create a CustomConnectionStringResolver pass in a customer ID to queury the Connection table to get the customer specific DB connection string. Then change the connectionString of our CustomerDbContext to the Customer Specific database instead of the default one. I have done this in other projects that use just basic EntityFramework and no ABL but not that works with ABP and the ConnectionStringNameAttribute. I want to do this with a DbContext that inherits from AbpDbContext<CustomerDbContext> and uses the ConnectionStringNameAttribute.

Any help would be appreciated.


3 Answer(s)
  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi, here is a simple example;

    [ConnectionStringName("CustomerDbContext")]
    public class CustomerDbContext : AbpDbContext<CustomerDbContext>
    {
        ......
    }
    
    [Dependency(ReplaceServices = true)]
    public class CustomConnectionStringResolver : MultiTenantConnectionStringResolver
    {
        private readonly ICurrentUser _currentUser;
    
        private readonly IDistributedCache _distributedCache;
        public CustomConnectionStringResolver
            (IOptionsSnapshot<AbpDbConnectionOptions> options,
            ICurrentTenant currentTenant, IServiceProvider serviceProvider,
            ICurrentUser currentUser, IDistributedCache distributedCache) :
            base(options, currentTenant, serviceProvider)
        {
            _currentUser = currentUser;
            _distributedCache = distributedCache;
        }
    
        public override string Resolve(string connectionStringName = null)
        {
            if (connectionStringName != null && connectionStringName == "CustomerDbContext")
            {
                var connectionString = ResolveCustomConnectionString();
                if (!connectionString.IsNullOrWhiteSpace())
                {
                    return connectionString;
                }
            }
            return base.Resolve(connectionStringName);
        }
    
        private string ResolveCustomConnectionString()
        {
            //query the custom connection string
            return _distributedCache.GetString(nameof(CustomConnectionStringResolver) + _currentUser.Name);
        }
    }
    
  • User Avatar
    0
    joe@tronactive.com created

    This is great thank you. So basically when I need to switch the customer context I will call the CustomConnectionStringResolver and just pass in the new connection string? or how is the resolver called?

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    It has replaced the default tenant resolver and full compatible, If it is not CustomerDbContext it will fall back to the default resolver. If you use the repository infrastructure provided by abp, it should work seamlessly.

Made with ❤️ on ABP v9.1.0-preview. Updated on October 11, 2024, 07:13