Separate DbContext for Identity and business operations with same database - is there any advantages?
Asked Answered
P

2

10

I've started working on an existing ASP.NET Core project that uses the Identity framework. The application uses a single database. For some reason the application uses two separate database contexts - one derived from IdentityDbContext which of course is used for managing User/Auth and the other derived from DbContext which is used for anything other than User-related business.

I've seen previously applications using two separate database contexts, but every time they were using a separate database through the IdentityDbContext. Maybe the previous developer(s) were trying to achieve something not clear to me.

So, what could be some possible advantages, which I might be missing, in my scenario of using two separate contexts while the application have a single database? Thanks.

Edit:

My understanding is, since I have a single database I could easily use only the IdentityDbContext and it would serve every purpose which currently two separate contexts combined are serving. The application has various business entities (let's say Employee, Customer, Supplier, etc) which are not User of the application, but can be made one at some future point by registration with respective level of role-based privileges. In such a scenario, using only the IdentityDbContext gives me the advantage of creating one-to-one relationship with the AspNetUsers table, which I cannot implement now simply because of the separate contexts.

Pontificals answered 24/7, 2019 at 6:15 Comment(0)
S
9

The only real "advantage", and it's slight, is that it conforms more to a bounded contexts philosophy: that each context should only work with a particular subdomain. However, in practical terms, you should also then have separate databases as well, or you're still mixing contexts. Additionally, if this is all in the same project, then there's zero point whatsoever. Even the idea of bounded contexts is a moot point in that scenario, since there's ultimately just one domain.

More likely than not, this was more accidental than intentional. When you create a new project with Individual User Accounts, an IdentityDbContext-derived class is added, to support the scaffolding. You can simply modify this scaffolded context to include your own additional entities, but particularly more green developers will often just add an additional context class for the app's entities. The fact that they're both using the same underlying database only leads credence to this being what likely occurred.

In short, there is no real advantage. The only benefit would come if you literally segregated these contexts such that the two were never available to the same project at the same time, i.e. they lived in separate class libraries and one or the other reference was added, depending on the particular domain the app is servicing. Short of that, it's entirely without point.

Salop answered 24/7, 2019 at 19:8 Comment(0)
S
4

This is based on the design of having single responsibility and a seperation of concerns.

Where a seperate context is a context that doesn't share tables with other contexts. Regardless where the tables are located.

The responsibility of the identity framework is to identify the user, using its own context. While the application has the business context to store business related data. The two have different responsibilities and both contexts have actually nothing in common except for the userid (or sub claim) which can be used to bind the two.

Simply put, with seperation of concerns, I can remove Identity without breaking my application. In other words, when I decide to replace identity for an sso implementation like IdentityServer4, shifting responsibilities, then I'll have no trouble migrating the users to the seperate tables of the Identity Provider.

With a single app you probably can't tell the difference, but as soon as the application becomes part of a larger platform, with multiple api's or when the responsibility of identifying the user needs to be replaced, then it will pay out.

But also for a single application I would recommend seperation of concerns. You'll need a good design when contexts are seperated. It increases maintainability and is easier to test, as changes in Identity do not touch the application and vice versa.

It also prevents mixing information that is not supposed to be mixed. E.g. you don't want to leak hashed passwords when all you want to do is display the users name.

For security reasons the business application should not have access to the identity context and the identity provider should remain ignorant of the business context. If information is missing then you should make sure it becomes part of the context, but not by joining contexts.

The problem with mixing contexts is, that in the end, it all becomes one context. Which means most likely that all tables have to become part of the Identity context. Please read my answer here for more thoughts about this.

Also consider a seperate context for authorization. Please read my answer here for more details.

Shigella answered 24/7, 2019 at 21:49 Comment(4)
Thanks for elaborating the possibilities nicely. Please, read the Edit. Do you then recommend not having such relationships?Pontificals
I would always recommend to have single responsibility and seperation of concerns. Because these are good design principles, even in small applications. It requires a certain perspective. It's not about how you can do it, but how you should do it. Also note that there is no relation between the business user and the identity user. It's authentication. Yes, there can be a logical relation using the UserId/Sub claim, but that's authorization. What is the logged in user allowed to access? I'm not here to convince you, it's up to you. But all I've written is what works for me in complex designs.Shigella
I went through the links to your other answers and I understand what you've written/said. I myself too is an avid follower of solid principle and separation of concerns. I'm just not that experienced with Identity framework and it's best practices. Thank you again.Pontificals
Doing just this now, and found your answer to help validate my design philosophy. Thanks!Martainn

© 2022 - 2024 — McMap. All rights reserved.