EF Core Multitenancy For Your SaaS Applications

  Рет қаралды 28,703

Milan Jovanović

Milan Jovanović

Күн бұрын

Пікірлер
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
Get the source code for this video for FREE → the-dotnet-weekly.ck.page/multitenancy Want to master Clean Architecture? Go here: bit.ly/3PupkOJ Want to unlock Modular Monoliths? Go here: bit.ly/3SXlzSt As a few awesome viewers have noted - the Tenant ID should come from a JWT or auth Cookie. I hoped that part was obvious since this is more of a proof of concept for Multitenancy. I wanted to focus on the EF features you can leverage to achieve this. And I left out the part about safely providing the Tenant ID. In any case, I'm updating this comment for posterity. TL;DR: For a production implementation, get the Tenant ID from the JWT/Cookie instead of passing it in a header. Join The .NET Weekly → bit.ly/4bfozSz It's a newsletter with 53,000+ engineers that teaches you how to improve at .NET and software architecture.
@JanKowalski-ld4ec
@JanKowalski-ld4ec 11 ай бұрын
Great, just defined my question and sec later found the answer below (being already published ;)
@artfulperch
@artfulperch 10 ай бұрын
Could it be a service behind the auth gateway, where the header value is assigned by a trusted service? Although a requirement to have the token with every request surely makes me feel more secure.
@d1ge
@d1ge 11 ай бұрын
I never really found joy in backend development. After your videos about DDD, code architecture etc. Im finally enjoying writing backend code. Keep it going!
@MilanJovanovicTech
@MilanJovanovicTech 10 ай бұрын
I always found backend work much more enjoyable 😁
@Wickerman1989
@Wickerman1989 11 ай бұрын
WOW. I recently had an interview about multitenancy, and I just popped these ideas out of my head - of course without implementation details.
@MilanJovanovicTech
@MilanJovanovicTech 10 ай бұрын
Did you pass?
@Wickerman1989
@Wickerman1989 10 ай бұрын
No, despite some good ideas I think they didn't want me due to lack of commercial experience with multi tenancy. Thanks for asking! @@MilanJovanovicTech
@Sqrlmasta
@Sqrlmasta 11 ай бұрын
This is exactly how I implemented multi-tenancy in my last application, but like you said in your pinned comment, also passed in the tenantId from a JWT. In addition, instead of of adding a query filter on each modelBuilder, I added a global query filter that adds this to all my entities matching a base type I created for everything that would be tenant-specific
@MilanJovanovicTech
@MilanJovanovicTech 10 ай бұрын
Smart way to solve the query filter part!👌
@sushant-um6iv
@sushant-um6iv 4 ай бұрын
Great idea!
@kodindoyannick5328
@kodindoyannick5328 10 ай бұрын
Thank you Milan. You tought me again something new. Two weeks ago i enrolled in your Pragmatic Clean Architecture course after followed you on LinkedIn and KZbin.
@MilanJovanovicTech
@MilanJovanovicTech 10 ай бұрын
Fantastic! Glad to hear that :)
@juanlopeztello7315
@juanlopeztello7315 11 ай бұрын
Adding a tenant_id claim inside a JWT is also a good option
@MaxSupercars
@MaxSupercars 11 ай бұрын
It's better option. I have written comment to this also.
@randomic_bear
@randomic_bear 11 ай бұрын
I'm actually implementing tenant_id instide the JWT token right now lol
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
Right, I was sure I mentioned that in the video but sadly I didn't. Updating my pinned comment!
@fifty-plus
@fifty-plus 11 ай бұрын
JWT is never a good option for general authn/authz despite it's popularity that all it's sprukers are trying to roll back now they know better.
@antonmartyniuk
@antonmartyniuk 10 ай бұрын
For the production app you need to check if a logged in user has access to a passed X-TenantId header. That way another user couldn't get data than doesn't belong to his tenant even if he somehow figures out the tenant identifier. This year my team was implementing a multi-tenant modular monolith application. We had some niche requirements where a user could have access to multiple tenants, single tenant or all tenants (i.e: super admin) defending on a role. It was the hardest use case of multi tenancy implemented by my lead
@MilanJovanovicTech
@MilanJovanovicTech 10 ай бұрын
Agreed, I noted in the comments that you should deal with the authentication aspect properly as I didn't cover that in this video
@holdenmoreland3119
@holdenmoreland3119 4 ай бұрын
Doing this right now with my team. Would love some details on what y’all did. We have considered using the Claims table to identify membership/specific permissions for each tenant by including the tenantId in this table. A super admin claim with the tech support tenantId grants admin access to everything.
@BlazorPlate
@BlazorPlate 11 ай бұрын
Thank you so much for the informative video. Multitenancy, in general, is a bit challenging, especially when it comes to managing tenants and their subscriptions through a dedicated tenant administration portal. This is in conjunction with data isolation strategies such as a Shared Database for All Tenants and a Separate Database Per Tenant. We dedicated the past four years to analyzing and studying the best practices that should be considered when building a SaaS app using the Multitenancy approach.
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
Do you have these best practices categorized somewhere? :)
@BlazorPlate
@BlazorPlate 10 ай бұрын
@@MilanJovanovicTech Yes, I do have :) I tried to post a long comment here but it gets removed automatically by YT algorithm due the restricted policy. Any workaround?
@MilanJovanovicTech
@MilanJovanovicTech 10 ай бұрын
@@BlazorPlate Try splitting the link like mywebsite . com
@BlazorPlate
@BlazorPlate 10 ай бұрын
Thanks for the suggestion! Try without spaces :) docs. google. com/ document /d / 1cl37hdOfTLjVDo80gE5TPu7QDW5SZf1jQaLPH16k_Ig/ edit
@BlazorPlate
@BlazorPlate 10 ай бұрын
@@MilanJovanovicTech Thanks for the suggestion. I also tried posting a comment as a link to google docs (with spaces) but I got caught!
@MaxSupercars
@MaxSupercars 11 ай бұрын
Milan this is not usable, this is not the way how multitenancy will be implemented. Maybe if you would implement both sides: frontend and backend. But as soon as you make your backend API public, it's not possible that other side on frontend will be controlling access to data via custom HTTP header. It would mean that any user who can log-in could use any TenantId in header and access to data of other users/tenants. The better solution is to either have own AuthN server (or at least AuthZ function after external login) and return TenantId as a claim in a JWT token which is issued by the server side and can be verified and not modified by client. Second part of video - the connection string for tenants are normally saved for each tenant in the database and loaded for ex. once at login and stored in local browser storage. Also it's not needed to store TenantId for the records. Better solution is to store just CompanyId. Imagine that common function is to move company to other Tenant. In this case you just change the relation between CompanyId and other TenantId and you're good. You have to have function like "Check TenantId against Company" for controlling of access to data of different tenants.
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
I know, this is a 15-minute video, for crying out loud 😅 Did you expect me to give you a production-ready solution? If we just update the part for how we fetch the Tenant ID from a different source, everything else holds true.
@orlandomalo7032
@orlandomalo7032 11 ай бұрын
What do you mean by "it's not needed to store TenantId for records", isn't it necessary to store the TenantId?
@MaxSupercars
@MaxSupercars 11 ай бұрын
@@orlandomalo7032 As I have written. You store the records just with CompanyId. The relation between TenantId and CompanyId you got in a separate table and maybe database for fast access at the time of login/authentication.
@MaxSupercars
@MaxSupercars 11 ай бұрын
@@MilanJovanovicTech Unfortunatelly it's very misleading and this solution gives the public the wrong way how to do it. In this case there is no difference between "home" and "production" version. Either it is done right or not right. And this is not. In 15 Minutes is possible to make the same video with other more secure solution like with JWT token etc.
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
@@MaxSupercars I think you and I have a different perspective of what a KZbin video should convey
@JanKowalski-ld4ec
@JanKowalski-ld4ec 11 ай бұрын
At last! Can't wait to watch on bigger screen! Thx!
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
Sorry for the long wait 😅
@Dombling
@Dombling 4 ай бұрын
Awesome video. It was what I needed in my project. Thank you !
@MilanJovanovicTech
@MilanJovanovicTech 4 ай бұрын
Glad it was helpful!
@ahmedtabba4891
@ahmedtabba4891 10 ай бұрын
Love it ❤ How to handle MIGRATIONS for multi DB scenario ❗️❗️
@MilanJovanovicTech
@MilanJovanovicTech 10 ай бұрын
Generate scripts, run them manually
@multistack
@multistack 6 ай бұрын
@@MilanJovanovicTech How We will hadnle When Tenant Grows after 3 to 4 years of production, Code must be improve
@Dpaz2009
@Dpaz2009 9 ай бұрын
That's a beautiful solution! Thanks for sharing!
@MilanJovanovicTech
@MilanJovanovicTech 9 ай бұрын
Glad you like it!
@mmacrobert
@mmacrobert 10 ай бұрын
Thanks for bringing clarity to this topic. Can you break down how to resolve tenants by using a sub-domain? Perhaps tenant-resolution is an abstraction in itself - perhaps by header, subdomain and even http-query-parameter.
@MilanJovanovicTech
@MilanJovanovicTech 10 ай бұрын
That'd be a topic for a different video
@vasugupta1
@vasugupta1 11 ай бұрын
I like your approach, but couldn't you create a DBContext Factory which returns you back a DBContext based on the tenantId you provided ?
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
Sure, seems possible
@zeelove5535
@zeelove5535 10 ай бұрын
can you teach completely how to use benchmarking with api projects .i love your videos.
@MilanJovanovicTech
@MilanJovanovicTech 10 ай бұрын
Can do
@zeelove5535
@zeelove5535 9 ай бұрын
thanks
@batressc
@batressc 6 ай бұрын
Always a good content quality! Thank you for sharing!
@MilanJovanovicTech
@MilanJovanovicTech 6 ай бұрын
My pleasure!
@RMarjanovic
@RMarjanovic 11 ай бұрын
I like the way you present the different tenant scenarios and how you automagically apply the tenantId in your queries. I didn't know you could use DI in the application DB context, to use values from an external service. Is this possible if using separate configuration files in combination with assembly scanning? I understand that you are only showing the basics in this video, but wondering if an improvement for a further video could be, using and validating JWT tokens. By accepting and reading the tenantId from the JWT token you protect against simply changing the tenantId in the header (if that's sensitive). You could just reference your video on JWT tokens in this video.
@matthewrossee
@matthewrossee 11 ай бұрын
That's basically the same thing, except you're checking against the tenant's id in the token. When dealing with cookies, you can have different cookie schemas for each tenant.
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
| Is this possible if using separate configuration files in combination with assembly scanning? - It should be, what do you think would prevent this? I was sure I mention it in the video, but yes - the TenantId is more likely to live in a cookie or JWT.
@RMarjanovic
@RMarjanovic 10 ай бұрын
@@MilanJovanovicTech well, when you say it, its the same functionality and process (ie per request handling) but getting it wired up is different, so you're pro'll right.
@randomic_bear
@randomic_bear 11 ай бұрын
I wonder if we could apply the query filter by convention if the entity thas the TenantId field, then apply automagically, instead of adding the query filter to every single entity (or worse, the new intern forgetting to add the query filter to a new entity)
@juanlopeztello7315
@juanlopeztello7315 11 ай бұрын
I saw something like that in stackoverflow if i'm not mistaken, it applied a configuration to all entities that implemented an interface, in this case could be something like ITenantModel
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
You can have your entities implement an interface, like ITenantId. The interface will have a single TenantId property. And then you should be able to say: modelBuilder.Entity().HasQueryFilter(). *Don't take this as 100% true, I didn't check in my IDE. But that's the idea.
@MiningForPies
@MiningForPies 11 ай бұрын
Be careful with query filters, they are not additive (well they weren’t before 8 I’ve not confirmed that yet). We had a filter like this to add the tenant id automatically to queries. But if you have another (in our case IDeletable) then the second filter replaces the first.
@wendysanarwanto6817
@wendysanarwanto6817 11 ай бұрын
Thank you for creating this helpful content, Milan ☺👏
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
Glad it was helpful!
@MiningForPies
@MiningForPies 11 ай бұрын
We have a multi tenant system where some data is shared. We created them to be hierarchical so tenants can create their own sub tenants
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
That's cool. Do you still have everything in a single DB or are you running in a multi DB setup?
@MiningForPies
@MiningForPies 11 ай бұрын
@@MilanJovanovicTech single db. The tenants are allocated to certain areas in the UK, but when a participant moves they will be transferred to a different tenant. A tenant can only view data that is linked to them, but they will get the data from the previous tenant to enable continuous service for the participant. (Project is in the criminal justice system so we get a lot of movement as people are transferred between and out of custody)
@truesoldier27
@truesoldier27 10 ай бұрын
Do you have a video showing how you set up those logs to show in the docker window?
@MilanJovanovicTech
@MilanJovanovicTech 10 ай бұрын
Just set the log level to Information
@HXI-l8l
@HXI-l8l 2 ай бұрын
That was a very useful video! Could you please post another one on implementing multi-tenancy using isolated databases for each tenant?
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
Great idea
@chuo129
@chuo129 11 ай бұрын
YEEEEEEEEEEES, I've been struggling with this theme a few weeks ago. Thank you so much for this video. Hope you can continue it
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
What does your solution look like?
@prathameshshende4
@prathameshshende4 11 ай бұрын
Great video. How can I set the tenant id into the header after login or call login api ?
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
You'd store it in the JWT (instead of using a header)
@subithsv
@subithsv 6 ай бұрын
I have a question here. In DB per tenant model, how identity storage should be structured and implemented?
@MilanJovanovicTech
@MilanJovanovicTech 6 ай бұрын
Probably as a separate persistence store. But some applications will also require the users to be partitioned.
@sergius1298
@sergius1298 10 ай бұрын
what if I got an unknown amount of tenants with same connection string but different database setting? How do I setup that one ?
@MilanJovanovicTech
@MilanJovanovicTech 10 ай бұрын
Place the "tenant-specific" tables into a custom schema, that could be one option
@mouradaissani8957
@mouradaissani8957 11 ай бұрын
great video, thank you, what about multi-tenancy with single db and many schemas? (each schema ==> tenant)
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
Similar to second scenario, except we'd configure the schema dynamically with HasSchema. Provisioning at the DB level is another headache.
@matthewrossee
@matthewrossee 11 ай бұрын
How would you implement this if you wanted to allow the SaaS admin to also sign in to this application and perform some actions like inviting the company via email or issuing broadcast notification for all tenants? This would require a different entity than Company.
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
You can have a different API for the admin that handles that, without any query filters
@matthewrossee
@matthewrossee 11 ай бұрын
@@MilanJovanovicTech But then the second API for SaaS admin can't access tables in the first DB right? Is there any other way to do that in one api?
@sunzhang-d9v
@sunzhang-d9v 10 ай бұрын
I don't have a TenantId before logging in, how do I know which database to access?
@MilanJovanovicTech
@MilanJovanovicTech 10 ай бұрын
You'll get one assigned when logging in. The value will typically be set in a JWT or Cookie
@alejandrasandoval5244
@alejandrasandoval5244 10 ай бұрын
How to use this multitenancy using hangfire too?
@MilanJovanovicTech
@MilanJovanovicTech 10 ай бұрын
In what way?
@PhantasyAI0
@PhantasyAI0 9 ай бұрын
what about multi-tenant database per tenant? Meaning only the databases are whats separated they share the same web api. Its been hard to learn how to do this with ef core. My idea is ill have a master database to store all tenant info and connection strings. When a tenant signs up for example, ill create there database on azure. Use ef core, add them to the master database. When I need to connect to the tenant database, I query the master database, grab the connection string some how make ef core work with dynamic connection strings. Create maybe a initial setup, where you run the first migration (similar to update-database in package manager console) on the tenants database. However most of this is theory, would love a video on this.
@MilanJovanovicTech
@MilanJovanovicTech 9 ай бұрын
Well you've got a pretty good idea going there
@vano4ok
@vano4ok 7 ай бұрын
Nice video. I have a question. How to make outbox pattern with separate databases? maybe job per tenant or something else
@MilanJovanovicTech
@MilanJovanovicTech 7 ай бұрын
Each DB would need its Outbox processor, I guess
@alejomillo7744
@alejomillo7744 6 ай бұрын
How you solve the Di of the service for running migrations? Since it throws a object null reference exception.
@MilanJovanovicTech
@MilanJovanovicTech 6 ай бұрын
We can check if it's null and only add the query filter in the null case. Another option is using a different DbContext for migrations.
@MarcusKaseder
@MarcusKaseder 10 ай бұрын
The TenantProvider can be registered as Singleton. HttpContextAccessor is also a singleton. It uses AsyncLocal to ensure the scope. So, it is not important to register it as scoped ;-)
@MilanJovanovicTech
@MilanJovanovicTech 10 ай бұрын
Not important, but this is a simplified example. A more real-world scenario would be fetching the Tenant from the DB, which could leverage EF
@GunChen-v5x
@GunChen-v5x 4 ай бұрын
Really useful, thanks, but in multiple database scenario, how to create a tenant ?
@MilanJovanovicTech
@MilanJovanovicTech 4 ай бұрын
We could have a dedicated tenant DB where we would first create a tenant, and then provision the required database
@raocarry7734
@raocarry7734 7 ай бұрын
I study a lot from your videos tks ,and I have a question how to change database connetctiongs when add a new tenant
@MilanJovanovicTech
@MilanJovanovicTech 7 ай бұрын
What's your current idea?
@Itfwf
@Itfwf 11 ай бұрын
That’s the Microsoft docs, can you make a more realistic scenario? What about auth in these scenarios?
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
That's a completely separate concern, IMO. It just comes down to how you fetch the Tenant ID value. Instead of getting it from a header, you'd fetch it form a JWT. Or use the User ID on the JWT to read the Tenant ID from the database. These are minor details in the overall scheme of things.
@christopherregula4610
@christopherregula4610 10 ай бұрын
Great video!
@MilanJovanovicTech
@MilanJovanovicTech 10 ай бұрын
Thanks!
@anandjaisy
@anandjaisy 5 ай бұрын
@MilanJovanovicTech How about the schema based multi-tenant, I know it is not supported in EF core. Is there a way to do that ?
@MilanJovanovicTech
@MilanJovanovicTech 5 ай бұрын
I think it's possible with the HasDefaultSchema method
@vincentbenazet3137
@vincentbenazet3137 5 ай бұрын
Hi Milan, thank you for your videos, they are great. I really like the part about filtering with EF Core, thanks :) I just have one point: I am not a big fan of doing the GetTenantId in the constructor because if there is an exception, it will be wrapped in a DI container exception (Autofac dependency injection exception). What do you think of the Finbuckle library for multi-tenant? I like it.
@MilanJovanovicTech
@MilanJovanovicTech 5 ай бұрын
But this isn't Autofac
@danvolovo5292
@danvolovo5292 11 ай бұрын
Good episode 👍. It would be enlightening if you used a more realistic scenario, instead of headers, determined tenantId using custom claims extracted from JWT. An idea for a future episode.😉
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
Didn't want to bother with JWTs/Auth, as I figured it would detract from the main point which is Multitenancy with EF
@boyakoosha
@boyakoosha 6 ай бұрын
Thanks for the effort, your videos are good and I appreciate the time like people yourself put into them. One question, in a Clean architecture with the core entities seperate from the main Infrastructure/Identity, what are people's view on creating entities that have relationships back to the individual user, rather than just the Tenant. For example, consider a "Keys" table maybe that is unique to the user logged in?
@MilanJovanovicTech
@MilanJovanovicTech 6 ай бұрын
I think it's fine, but wouldn't it still be scoped to a tenant also?
@thanasakis61
@thanasakis61 10 ай бұрын
Hi Milan, I would like to note here that the firtst approach with the EF Query Filters is applicable when your users or tenants exists outside of this application. For example I have an MVC asp net core application and users are inside the same application (monolith) which makes it a mutlitenant application since every user can only access and modify their own data and all of them exist in the same databse. However the approach with the app user resolver service did not work for me. THe reason is because the OnModelCreating method is only called once for the project's lifetime. So before anyone would login the query filters had alreaady instatiated with null as the tenantId. I was actually around this issue for some time but for this type of application i mentioned it seems it is not an applicable solution. Great video, Keep up the good work!
@MilanJovanovicTech
@MilanJovanovicTech 10 ай бұрын
But if the DbContext is scoped - it should pulling the same scoped service to configure the Query Filter. Right?
@thanasakis61
@thanasakis61 10 ай бұрын
true but my DbContext is scoped by default however the OnModelCreating get executed only the first time. A similar issue was discussed on StackOverflow about tenants on the same application.@@MilanJovanovicTech
@daymaker_trading
@daymaker_trading Ай бұрын
THANK YOU so mcuh! Such a gem information!
@MilanJovanovicTech
@MilanJovanovicTech Ай бұрын
Happy to help :)
@sunzhang-d9v
@sunzhang-d9v 10 ай бұрын
Isn't it through TenantId that multiple databases determine which database to connect to? Before logging in, I don't know TenantId. How can I connect to the database and obtain user information? Is there a separate database for login logic?
@MilanJovanovicTech
@MilanJovanovicTech 10 ай бұрын
The identity service can live separately, yes. And after logging in you collect the required information.
@andreituduce6127
@andreituduce6127 10 ай бұрын
Hello, How would you do it if the connection strings would have to be dynamic as well for the single tenancy case? Ex: Company x and Company y both registered within the application and you have to build dynamic databases for both of them without modifying the current app.configuration file I also enjoy your content, keep it up!! Thank you!
@MilanJovanovicTech
@MilanJovanovicTech 10 ай бұрын
Have a set of migration SQL scripts that create the required database structure. Run it in the background when a company registers. Something along those lines.
@sunzhang-d9v
@sunzhang-d9v 11 ай бұрын
Does TenantId need to be purchased? How to deal with it?
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
It's just a way to identify a customer or group of users
@VicheaNath
@VicheaNath 4 ай бұрын
What is base way to use with dapper
@MilanJovanovicTech
@MilanJovanovicTech 4 ай бұрын
Always include the tenant ID in the query
@orestpavlenko860
@orestpavlenko860 9 ай бұрын
Hi. How i can setup individual users which does not have tenant?
@MilanJovanovicTech
@MilanJovanovicTech 9 ай бұрын
Update the query filter
@MahmoudMouradSidky
@MahmoudMouradSidky 6 ай бұрын
Thank you for the pro content
@MilanJovanovicTech
@MilanJovanovicTech 6 ай бұрын
Sure thing!
@joyguan1476
@joyguan1476 8 ай бұрын
Wouldn't data leak to another tenant if they changed the header value that holds the tenant id?
@MilanJovanovicTech
@MilanJovanovicTech 8 ай бұрын
Check the pinned comment
@emreteoman1564
@emreteoman1564 11 ай бұрын
What is the best database migration strategy in case each tenant has different databases?
@drhdev
@drhdev 11 ай бұрын
Different migrations
@MilanJovanovicTech
@MilanJovanovicTech 10 ай бұрын
EF still works, but at some point it becomes smart to manage the DB migrations yourself.
@Sanatani-k1s
@Sanatani-k1s 8 ай бұрын
Will this resolves concurrency? As multiple concurrent tenants using at same time? e.g. in terms of lambda functions. I am new to this by the way..
@MilanJovanovicTech
@MilanJovanovicTech 8 ай бұрын
Wouldn't each lambda run inside its own context?
@jorgepedraza1275
@jorgepedraza1275 11 ай бұрын
Excellent. As always, there is no free repository related to the video. Any sales channel through Amazon to buy your complete course🤔
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
Not really, no
@adnenbenawicha5082
@adnenbenawicha5082 7 ай бұрын
Thank u for the video, can u make a video on migrations with multi tanécy please ?
@MilanJovanovicTech
@MilanJovanovicTech 7 ай бұрын
Will consider
@CarlosCortes-dp1ci
@CarlosCortes-dp1ci 6 ай бұрын
Hi Milan, I am a dedicated follower and student of your two courses. Do you have any plans for a course focused on multitenancy or SaaS applications? Any recommendations you could give me for my project? I would like to follow the strategy of using EF Core for commands and Dapper for queries. Additionally, I would like to use Keycloak as the identity provider for the different tenants. Thank you for your videos; they are very helpful for our projects and for improving as software architects.
@MilanJovanovicTech
@MilanJovanovicTech 6 ай бұрын
Not in the recent future, no. I might do a longer video about multitenancy for YT
@dimitarelkov28
@dimitarelkov28 10 ай бұрын
Come on… It is basic concept of multi tenancy. It’s a great presentation. For the goal of the POC it was kept simple as possible. Of course it can be extended based on everyone’s requirements. Important and focus is EF support here, because this can be achieved also without EF Core.
@MilanJovanovicTech
@MilanJovanovicTech 10 ай бұрын
Everyone wants to see a production-ready tutorial in 10 minutes these days 😁
@dimitarelkov28
@dimitarelkov28 10 ай бұрын
@@MilanJovanovicTech people just don’t want to think
@CarCan316
@CarCan316 5 ай бұрын
This may seem like a novice question, but if the SasS application is going to be used for multiple domain names, where each spins up its own instance of the application with its individual frontend, if anyone has an example of how to solve that issue, I'd be very interested to see how thats done.
@MilanJovanovicTech
@MilanJovanovicTech 5 ай бұрын
We should be able to figure out the tenant based on the domain name, I think Derek has a good video about that if you check out his channel
@CarCan316
@CarCan316 5 ай бұрын
@@MilanJovanovicTech Thank you, Milan, that sounds exciting. If you can let me know what the channel name is or a link to it, that would be most helpful! Also, just wanted to say, your videos are pretty damned interesting, the subject matter you are choosing to cover is awesome. Thanks again!
@TheAzerue
@TheAzerue 11 ай бұрын
I wondering how DbContextConnectionPool would work ?
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
It should work, in theory. Worth testing out the second scenario though 🤔
@banzeirao
@banzeirao 5 ай бұрын
Ok but when generate efcore migrations with efcore tool: Unable to create a 'DbContext' of type ''. The exception 'Tenant ID not present'
@MilanJovanovicTech
@MilanJovanovicTech 5 ай бұрын
I like that 😁
@amirologi
@amirologi 11 ай бұрын
Does anyone know the docs for creating a service? Please send the link.
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
What do you mean by service?
@amirologi
@amirologi 10 ай бұрын
@@MilanJovanovicTech I mean the provider: Services > TenantProvidor kzbin.info/www/bejne/fZeUpHasntCjnas
@amirologi
@amirologi 10 ай бұрын
@@MilanJovanovicTech I mean the provider
@MilanJovanovicTech
@MilanJovanovicTech 10 ай бұрын
@@amirologi www.milanjovanovic.tech/blog/multi-tenant-applications-with-ef-core
@Wouldntyouliketoknow2
@Wouldntyouliketoknow2 11 ай бұрын
It doesnt have to come from the JWT it can also be inferred from the url like a subdomain per tenant.
@MilanJovanovicTech
@MilanJovanovicTech 10 ай бұрын
That involves a whole lot more infrastructure, though
@Wouldntyouliketoknow2
@Wouldntyouliketoknow2 10 ай бұрын
@@MilanJovanovicTech I disagree. Whilst it would typically require a wildcard SSL certificate (so that requests for multiple subdomains hit the ingress), I'm not sure that qualifies as whole lot more infrastructure as typically you'd have an ssl cert anyway. For local development you can add a few entries to your etc/hosts file e.g "foo.localhost" pointing to loopback ip. I would say it requires some very minor configuration to achieve. The main thing is whether its a requirement that tenants have their own subdomain. The benefits are it allows tenant identification prior to user authentication - so they can be served customised "public" pages and they can also have their own authentication / login page based on tenant settings - one tenant may use their own SAML idp versus another who uses native login. In other words the decision is more requirements based than infrastructural.
@marna_li
@marna_li 11 ай бұрын
Thank you! Btw. The "X-" convention in "X-TenantId" is no longer considered necessary as per RFC 6648 🙂
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
I prefer having a convention for custom headers to make them easier to track
@drhdev
@drhdev 11 ай бұрын
No longer necessary but good practice
@sunzhang-d9v
@sunzhang-d9v 11 ай бұрын
Logging in with a separate database?
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
What do you mean?
@dotnetMasterCSharp
@dotnetMasterCSharp 4 күн бұрын
useful content
@MilanJovanovicTech
@MilanJovanovicTech 4 күн бұрын
Glad you think so!
@drhdev
@drhdev 11 ай бұрын
I hope people understand that this is an example only and you should NEVER EVER do this in production
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
Which part exactly? Because we definitely used Tenant-based query filters in production on a 1M+ users SaaS.
@drhdev
@drhdev 10 ай бұрын
The security part obviously. Query filters are fine. You’re treating a tenant like an api key when you should do a lookup on the user credentials.
@cloudwoofer
@cloudwoofer 10 ай бұрын
@@drhdev yeah, I bet the video would get more and more complex the closer it is to reality so Milan chose to cut it short
@remyjoseacostamelo
@remyjoseacostamelo 11 ай бұрын
🥷🏾🔥
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
💪🚀
@eugene5096
@eugene5096 11 ай бұрын
Tenant could be passed via part of route
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
Wouldn't that expose tenant info in the logs?
Mapping Domain-Driven Design Concepts To The Database With EF Core
18:06
Milan Jovanović
Рет қаралды 55 М.
Multi-Tenant: Database Per Tenant or Shared?
8:55
CodeOpinion
Рет қаралды 21 М.
Sigma girl VS Sigma Error girl 2  #shorts #sigma
0:27
Jin and Hattie
Рет қаралды 124 МЛН
Жездуха 41-серия
36:26
Million Show
Рет қаралды 5 МЛН
GIANT Gummy Worm #shorts
0:42
Mr DegrEE
Рет қаралды 152 МЛН
Get Rid of Exceptions in Your Code With the Result Pattern
13:06
Milan Jovanović
Рет қаралды 57 М.
Event-Driven Architecture (EDA) vs Request/Response (RR)
12:00
Confluent
Рет қаралды 178 М.
Multi-Tenant SaaS Architecture (Next.js Auth)
22:57
ByteGrad
Рет қаралды 30 М.
7 Serilog Best Practices for Better Structured Logging
13:36
Milan Jovanović
Рет қаралды 29 М.
Multi-tenancy architecture | The Backend Engineering Show
25:29
Hussein Nasser
Рет қаралды 42 М.
Exceptions Are Extremely Expensive… Do This Instead
17:15
Milan Jovanović
Рет қаралды 49 М.
SQLc is the perfect tool for those who don't like ORMs
28:11
Dreams of Code
Рет қаралды 112 М.
Multi-tenant Architecture for SaaS
11:07
CodeOpinion
Рет қаралды 124 М.
Vertical Slice Architecture Project Setup From Scratch
22:43
Milan Jovanović
Рет қаралды 65 М.
EF Core Migrations Deep Dive, Applying Migration, SQL Scripts
16:41
Milan Jovanović
Рет қаралды 17 М.