Your approach is not true by design. I will explain why.
This is the DbContext comes with the template:
public class AbpProjectNameDbContext : AbpZeroDbContext<Tenant, Role, User>
{
//TODO: Define an IDbSet for your Entities...
/* NOTE:
* Setting "Default" to base class helps us when working migration commands on Package Manager Console.
* But it may cause problems when working Migrate.exe of EF. If you will apply migrations on command line, do not
* pass connection string name to base classes. ABP works either way.
*/
public AbpProjectNameDbContext()
: base("Default")
{
}
/* NOTE:
* This constructor is used by ABP to pass connection string defined in AbpProjectNameDataModule.PreInitialize.
* Notice that, actually you will not directly create an instance of AbpProjectNameDbContext since ABP automatically handles it.
*/
public AbpProjectNameDbContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
}
//This constructor is used in tests
public AbpProjectNameDbContext(DbConnection existingConnection)
: base(existingConnection, false)
{
}
public AbpProjectNameDbContext(DbConnection existingConnection, bool contextOwnsConnection)
: base(existingConnection, contextOwnsConnection)
{
}
}
ABP uses the 2nd constructor (AbpProjectNameDbContext(string nameOrConnectionString)) here, as stated in the comment. Default constructor is only used while you are working with PMC, like executing update-database.
So, you should add a constructor like
public SaaSZeroDbContext(string nameOrConnectionString)
: base(GetConnectionStringFromUrl())
{
}
This ctor will be called by ABP, but you ignore nameOrConnectionString and generating it dynamically. That's OK. But there is still a problem. When you use PMC commands (like update-database), HttpContext.Current will be null. Because this execution will not be in a HTTP Context. Also, in unit tests there is no HttpContext.Current and so on.
So, your GetConnectionStringFromUrl() method should be able to work even if HttpContext.Current is null. If it's null, you can return a default connection string, for example.
Although this approach can work, I don't suggest it. ASP.NET Boilerplate already provides a way of dynamically determining the connection string on the runtime.
Create a new class that implements IConnectionStringResolver. You can derive your class from DefaultConnectionStringResolver and override GetNameOrConnectionString method too. Thus you can call base.GetNameOrConnectionString if HttpContext.Current is null and your code fallbacks to default implementation.
Replace IConnectionStringResolver with your own implementation as documented here.
HttpContextfrom the controller to your method as an argument