Last post Jan 10, 2019 05:10 PM by mgebhard
Jan 09, 2019 08:41 PM|jlpm|LINK
I have an ASP.NET Core 2.2 Portal. I also use EF Core. Everything I talk about is hosted in Azure.
The Portal has a database (PortalDb) to take care of Identity and relate a person to a Customer. Once a user is identified, they are given access to customer-specific data. Because of the nature of the data, each Customer must have their own database (hard
requirement; CustomerDb). These are in an Elastic Pool for resource management.
Can someone explain to me the best way to ensure I have the correct CustomerDbContext for each user? I'm trying to understand the life-span and exposure of a Scoped service. I have the DatabaseService service expected to manage this dynamic database connection
that will be included in all services that need to interact with that Customer's database. It is included in the Startup.ConfigureService method:
Thanks in advance for your help,
Jan 09, 2019 10:06 PM|bruce (sqlwork.com)|LINK
You want a scoped DbContext, but it need to point to the correct database. you should use middleware, that updates the scoped DbContext with the correct database name. it can use the user name from authentication (so the middleware runs after authentication)
to determine the database name. you could place the database name in the login cookie as a Claim.
Jan 09, 2019 10:11 PM|jlpm|LINK
This sounds cool. However, I am somewhat new to ASP.NET Core and have not yet defined a middleware (read about it). I'll start researching but to go down this path quicker I'd appreciate some sample code.
Can you tell me why my Scoped Service approach doesn't get me there?
Jan 10, 2019 01:19 AM|bruce (sqlwork.com)|LINK
Jan 10, 2019 10:42 AM|yogyogi|LINK
Your question is regarding Dependency Injection (DI) and using DI in Entity Framework core. The DbContext class can be added as a service in Starup.cs class and so you can use it in your Controller
without having to manually create it's object. I would suggest you to have a look on this tutorial to understand it - ASP.NET
Core — How to use Dependency Injection in Entity Framework Core
Jan 10, 2019 04:14 PM|jlpm|LINK
That is a nice tutorial but, I'm not sure what gave you the impression that I didn't know about DI. I use DI to put the DbContext into my DatabaseService. Then, I use DI to pass the DatabaseService to everything that needs it. The DatabaseService has
a method that gets the context for me using whatever database name I give to it.
The article did build my confidence, however, because it showed me I was on the right track. :)
Jan 10, 2019 04:25 PM|jlpm|LINK
Let me narrow the scope of this question down. This article talks about the lifetime of a service:
It says that a "Scoped lifetime services are created once per request." My background is in Desktop development so I'm not satisfied with the depth of this answer and the concept of multiple sessions of the same binary running at the same time has
been hard for me.
Thanks again for your help,
Jan 10, 2019 04:42 PM|jlpm|LINK
By narrowing down my question it helped me to narrow my search. I would still like to hear an answer pertaining to my last questions. But, I believe this is the concept that I am trying to get right:
Jan 10, 2019 05:10 PM|mgebhard|LINK
First, what is a request?
Clicking a link or button causes the browser to submit an HTTP request.
If I have 200 people logged in so there are 200 concurrent sessions running how does it work when I'm passing around my DatabaseService?
There are 200 potential requests which can create 200 potential DatabaseService instances (scoped) if everyone clicked a submit button at the same time.
Or, is it isolated each time a new page is loaded?
The C# code runs on each request. Any instance classes created during a request are torn down by the time the response reaches the browser.
How do I ensure that each user can see only the data store they are expected to see?
HTTP is stateless. In browser based applications the user's identity is stored in a token within a cookie. .NET has middleware that knows how to read the cookie/token and add the contents to the current request. You can use this user "claim" to find the
correct connection string.
So again, what is the scope, lifetime and exposure of my DatabaseService?
ASP.NET Core defines service scope in the following doc.
As suggested you'll want to build a DbContext factory so you can control how the context is built when injected.