Last post Jun 12, 2019 12:54 PM by deepalgorithm
Jun 12, 2019 07:47 AM|f.a.rodriguez|LINK
I have an ASP .Net Core 2,2 Web API, which uses SignalR. I need to save messages sent to the hub (from the client) to the database, so I need an instance of DbContext in my hub. I've got that, but because this is a multi-tenant application, I need to set
the connection string of the DbContext depending which client is sending the message.
public class ChatHub : Hub
private IServiceProvider _serviceProvider;
public ChatHub(IServiceProvider serviceProvider)
_serviceProvider = serviceProvider;
public async Task SendMessage(string user, string message)
using (var scope = _serviceProvider.CreateScope())
var dbContext = scope.ServiceProvider.GetRequiredService<TenantContext>();
// Set dbContext ConnectionString
Message newMessage = new Message(user, message);
} await Clients.All.SendAsync("ReceiveMessage", user, message);
As you can see, I'm creating a scope in my hub, and then requesting the DbContext. However, because this is a multi-tenant application, the DbContext's ConnectionString isn't set (it's NULL). The connection string normally gets set by reading a
TenantId header in the HTTP requests from the client to the API (in some middleware) which gets saved in HttpContext. Then, in my DbContext.OnConfiguring() method, I create the connection string based on what was saved in HttpContext (in the
However, when the client sends a message to the hub, it doesn't trigger the middleware. This means that when I create a scope and grab a DbContext, DbContext.OnConfiguring() isn't able to set the connection string because the middleware never fired to read
the TeantId off of the HTTP request header.
My question is, Is it possible to manually set the DbContext's connection string in my hub?
Jun 12, 2019 11:41 AM|DA924|LINK
Yeah, you can probably do it, but it would have to be based on some functionality you created yourself to get the connectionstring to the DbContext.OnConfiguring() at time of execution.
You could look into using IOptions, a custom class of connectionstrings, and a tenant indicator being passed into the DBContext's constructor. The OnConfiguring() would call this connectionstring selection function to select the connectionstring to use
I kind of show how to get the connectionstring to OnConfiguring() that uses the custom function that returns the connectionstring in the below thread.
Maybe, the light bulb will come on for you where you can create something that will work for you.
Keep in mind that there are EF Core tools or techniques that will allow you to update the Dbcontext and not disturb existing code in the Dbcontext.
Jun 12, 2019 11:43 AM|deepalgorithm|LINK
This is how you can do it.
var options = new DbContextOptionsBuilder<TenantContext>()
.UseSqlServer("YOUR CONNECTION STRING")
using (var context = new TenantContext(options))
Jun 12, 2019 11:56 AM|f.a.rodriguez|LINK
Thanks deepalgorithm. I'm just not sure how to provide the options object o the TenantContext object the way I'm calling the service:
using (var scope
Where do I stick options in the above example?
Jun 12, 2019 12:23 PM|deepalgorithm|LINK
If I understood your question, you want to dynamically create an instance of your DbContext class within your Hub method. You do not need to do anything with scope. Just do what I showed you. I'm not sure where you will get the connection string though.
Regardless, this is how you can manually set up a DbContext.
Jun 12, 2019 12:36 PM|f.a.rodriguez|LINK
Thanks deepalgorithm. I was creating a scope because I read that's how one should request a DbContext service in a SignalR hub. But I just tried without the scope (like you suggested) and it worked perfectly. Thank you!
Jun 12, 2019 12:54 PM|deepalgorithm|LINK
Great. Happy I was able to help you out.