- the API has code redundancy: given a resource (e.g. PersonDemo), there is one controller per each DB type, one interface/service per each DB type, all of them duplicating the code for retrieve, update, maxId, etc functions.
- there might exist typos in the DataContextFactoryXXX classes: they always set configuration for SQLServer ( var options0 = new SqlServerDataContextOptions(connectionString); )
- I dont see where cachenames are parameterized, the API only connects to "Manager" cachename (which is string hardcoded!), while the other 2 cachenames (PersonDemo01 and ConectionManager) are never used.
- Interfaces, controllers, services, models are all named after the DB type (e.g , see "SQL" repeated in classes'name DSSQLPersonDemoController, PersonDemoSQL, IDSSQLPersonDemoService, DSSQLPersonDemoService).
This said, I thank you again for paving the way on how to handle this problem in SnapObject's DataContext object and AddDataContext function. With the help from Appeon, I attach a simpler solution that avoids the four flaws above.
Goal is to parameterise cachenames, which for example can be sent by the client as easy as in the http request's header:
restclient.SetRequestHeaders( "CacheName:"+ ls_CacheName )
restclient.Retrieve(dw_dept, "https://localhost:5001/api/Department/Retrieve")
The API wil rely on same concept of data context factory you posted
services.AddScoped<DefaultDataContext>(provider => provider.GetService<DataContextFactory>().CreateDataContextSQL())
but it accesses current HttpContext and Config to build the connection string dynamically:
public DataContextFactory(IConfiguration config, IHttpContextAccessor httpAccessor)
{
_config = config;
_httpAccessor = httpAccessor;
}
public DefaultDataContext CreateDataContextSQL()
{
string cacheName = _httpAccessor.HttpContext.Request.Headers["CacheName"].ToString();
string connectStr = _config[$"ConnectionStrings:{cacheName}"];
var options = new OdbcSqlAnywhereDataContextOptions(connectStr);
return new DefaultDataContext(options);
}
Best,
.m