Open Closed

Override Connection String For Tenant #5175


User avatar
0
jpatron created
  • ABP Framework version: v6.0.3
  • UI type: MVC
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): yes
  • Exception message and stack trace: N/A
  • Steps to reproduce the issue:" N/A

Hello,

I created a setting to determine whether the tenant should use a specific connection string to a database with real data or another connection string that points to a "demo" database. I followed the idea of overwriting the connection string by calling a method under ConfigureServices in our web application module as suggested by the following link: https://docs.abp.io/en/abp/6.0/Connection-Strings However, if I try to get the ISettingsManager at that point, it is always null. I have also tried getting IServiceProvider and ServiceProvider with the same unsuccessful results. Here is the method I am using to accomplish this task:

private async Task ConfigureDemo(ServiceConfigurationContext context, IConfiguration configuration)
    {
        var settingProvider = context.Services.GetObjectOrNull<ISettingManager>();
        if (settingProvider != null)
        {
            var useDemoDb = await settingProvider.GetOrNullForCurrentTenantAsync(<Our_App>Settings.UseDemo);
            if (useDemoDb.Equals("True", StringComparison.OrdinalIgnoreCase))
            {
                Configure<AbpDbConnectionOptions>(options =>
                {
                    options.ConnectionStrings["RealDataDb"] = configuration.GetConnectionString("DemoDb");
                });
            }
        }
    }

Do you have any ideas or suggestions on how we can solve this problem? Thanks in advance!


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

    Hi,

    You can consider to replace the Connection String Resolver https://docs.abp.io/en/abp/6.0/Connection-Strings#replace-the-connection-string-resolver

  • User Avatar
    0
    jpatron created

    Hi,

    I have created a CustomConnectionStringResolver as you suggested, but now I have a follow-up question. The Default connection is stored in the host database for each tenant. However, the connection I am trying to overwrite is stored in appsettings.json, not in the host database. When I debug into the ResolveAsync method of my CustomConnectionStringResolver, it doesn't seem to find the connection I am looking for. Here is my updated ResolveAsync method:

    public override async Task<string> ResolveAsync(string connectionStringName = null)
    {
        if (_currentUser.IsAuthenticated && _currentTenant.Id != null)
        {
            var useDemo = await _settingManager.GetOrNullForCurrentTenantAsync(AppSettings.UseDemo);
            if (useDemo?.Equals("True", StringComparison.OrdinalIgnoreCase) == true
                && connectionStringName != null
                && connectionStringName == "RealDataDb")
            {
                var connectionString = _configuration.GetConnectionString("DemoDb");
                if (!connectionString.IsNullOrWhiteSpace())
                {
                    return connectionString;
                }
            }
        }
    
        return await base.ResolveAsync(connectionStringName);
    }
    

    Both "RealDataDb" and "DemoDb" connection strings are stored in appsettings.json. Can I still use this method to decide which connection to use depending on the value of the useDemo setting?

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    I think this way should work.

    You also need to override the Resolve method.

    BTW, you can share a project that can reproduce the problem with me if it's still not working for you. shiwei.liang@volosoft.com I will check it.

  • User Avatar
    0
    jpatron created

    Hi,

    I managed to accomplish the connection change. However, we are using a distributed cache for the entities within the "RealDataDb" context. Is there a way to reset the distributed cache for those entities, or remove them from the cache? Also, I noticed that this method gets called pretty frequently, is that expected?

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Is there a way to reset the distributed cache for those entities, or remove them from the cache?

    You need to manually remove the bold change using the code:

    IDistributedCache<....> cache;
    
    cache.RemoveAsync();
    cache.RemoveManyAsync()
    

    Also, I noticed that this method gets called pretty frequently, is that expected?

    Yes.

Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
Do you need assistance from an ABP expert?
Schedule a Meeting
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v9.3.0-preview. Updated on April 16, 2025, 12:13