Hi,
I'm working on my first .Net DataStore Web Api project and it is really different from PBScript. On DB Server we have many databases (same structure) for different customers (tenants) and I would like to send the database name via HTTP header like:
inv_RESTClient.SetRequestHeader("DbName", "MyDbName")
How can I handle this on Web Api project?
Today I have a appsettings.json:
{
"ConnectionStrings": {
"Test": "Data Source=SRVDB,1433;Initial Catalog=MyDb;Integrated Security=False;User ID=sa;Password=adm;Pooling=True;Min Pool Size=0;Max Pool Size=100;MultipleActiveResultSets=False;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite"
}
}
and the TestDataContext.cs:
using SnapObjects.Data;
using SnapObjects.Data.SqlServer;
namespace Test
{
public class TestDataContext : SqlServerDataContext
{
public TestDataContext(string connectionString)
: this(new SqlServerDataContextOptions<TestDataContext>(connectionString))
{
}
public TestDataContext(IDataContextOptions<TestDataContext> options)
: base(options)
{
}
public TestDataContext(IDataContextOptions options)
: base(options)
{
}
}
}
and startup.cs:
...
namespace Test
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(m =>
{
m.UseCoreIntegrated();
m.UsePowerBuilderIntegrated(); //add UsePowerBuilderIntegrated
});
// Original AddDataContext
//services.AddDataContext<TestDataContext>(m => m.UseSqlServer(this.Configuration, "Test"));
// Actual AddDataContext
string DbName = "MyDbName"; // ==>> I would like to get de HTTP Request Header "DbName" at this point
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(Configuration.GetConnectionString("Test"));
builder.InitialCatalog = DbName;
services.AddDataContext<TestDataContext>(m => m.UseSqlServer(builder.ConnectionString));
...
Thanks.
Marcos
PB 2019 R3 Build 2670
Armeen - are you suggesting Marcos have a DataContext class for each "tenant", and register each for dependency injection in ConfigureServices(...)? Would each Service class receive the all the DataContext classes by dependency injection in their constructor, and then choose which to use based on an API parameter?
How about forgetting about dependency injecting the database context, and just instantiating it when needed in the Service code, when you know which connection string to pass?
One over-arching comment I would like to make: No-one should underestimate the complexity of adapting to ASP.NET Core and C# by even very experienced PB developers. It is a completely new and much more complex world - especially if you are trying to adhere to best practices developed in that world over many, many years. Myself, I am getting there, but it has been a very difficult journey, and most documentary materials have not made that journey any easier.
Dependency injection is not a requirement in ASP .NET Core, it's just a code pattern that has a lot of benefits, like swapping out implementations in only one place while affecting every place it's used. There's nothing forbidding you from instantiating the DataContext manually, and while that's one way to do what you want, it will incur in more code, make maintenance harder and if you ever want to change the connection parameters or swap out the implementation altogether, you would need to go to every place you're using that specific DataContext.
Just something to keep in mind.
Regards,
Francisco