Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

netcore dependency injection per user

I am wondering how to set up the netcore dependency container for mvc with one instance per user.

According to https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection#service-lifetimes-and-registration-options there are currently only three methods of specifying a lifetime: singleton(one instance per application), scoped (one instance shared within a HttpRequest), transient (one instance per DI instance request)

Has someone attempted to do create on instance per user yet? I would be curious how it's done - if not i will probably dig through the docs at some point to see how it can be done and share the solution.

like image 353
Dbl Avatar asked Oct 23 '25 19:10

Dbl


2 Answers

Create instance on first user request and keep it alive (for next requests) until with some expiration timeout... This looks like a Sessions.

You may register your service with factory method and analyze current Session inside.

like image 165
Dmitry Avatar answered Oct 26 '25 18:10

Dmitry


If this is an asp.net core application, middleware that is automatically added to the middleware pipeline handles creating a new DI scope at the start of a request, and disposing of that scope at the end of a request. This scope is stored in HttpContext. This scope will be used when injecting MVC controllers etc. Therefore if you want to have per-user services injected into your MVC controllers / action methods, you'll need to replace this scope in HttpContext with your own one built for the current user. You'd have to do this with middleware which would have to run after the authentication middleware (so after the current user was established). Your custom middleware would look at the current authenticated user, and the GetOrCreate the IServiceProvider (container) held in some cache with probably a sliding expiry. With the per user IServiceProvider in hand, it would then create a scope for the current request and replace the scope currently in HttpContext with this user specific one, also ensuring its disposed of at the end of the request. The thing is, when building the per user container, if you create a new ServiceCollection for each user and register a few services and build and cache that IServiceProvider for that user, you won't be able to resolve any services that you've only registered at the application level I.e on startup. This is where the concept of child containers are handy, which microsoft doesnt implement out of the box, but you can use if you switch to using another DI provider like Autofac. Autofac provides an implementation of IServiceProvider and the ability to spawn child containers. If you used this mechanism you could create a child container for each user, which means it would still be able to resolve all your higher level services, but now you can also resolve the user specific services. If you do all this, you'll be able to have per user services injected.

It's a fair amount of work. If there is enough interest I'd consider adding this feature to my multitenancy library as it already does something similar to create per tenant containers: https://github.com/dazinator/Dotnettency

like image 42
Darrell Avatar answered Oct 26 '25 19:10

Darrell



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!