Skip to content
This repository has been archived by the owner on Nov 2, 2018. It is now read-only.

Throw when accessing a scoped service from a non-scoped service #88

Closed
rynowak opened this issue Jun 6, 2014 · 3 comments
Closed

Throw when accessing a scoped service from a non-scoped service #88

rynowak opened this issue Jun 6, 2014 · 3 comments

Comments

@rynowak
Copy link
Member

rynowak commented Jun 6, 2014

We hit an instance of this in MVC - see aspnet/Mvc#631

UrlHelper is a scoped service - and an attempt was made to resolve it from inside a singleton.

Can we throw if this happens?

@victorhurdugaci
Copy link
Contributor

While you might shoot yourself in the foot if you reference a scoped service from a non-scoped service (or more generic, a narrow scoped service from a broader scoped one), there are scenarios that are totally valid for such a use case. You might have a problem if you keep a reference to such service but if it is a single use service, it might work just fine.

Here is a valid example: a singleton that uses an EF connection once to get some data from the DB. The connection is used only in the constructor and then it can be disposed. If this wouldn't be allowed, the alternative would be to hack two service registrations.

I looked at what NInject does and it doesn't prevent you from doing this.

cc @halter73

@halter73
Copy link
Member

halter73 commented Dec 5, 2014

Autofac also allows you to inject scoped services into singletons, so I'm leaning toward allowing in ServiceProvider too.

Even so, it's easy to be unaware of the full implications of doing this. Take the example of using an EF connection in a singleton constructor. Even though the EF connection is registered as a scoped service, it effectively becomes singleton once it is injected into a singleton service.

You are generally not supposed to dispose injected services. The IoC container does that for you when the scope ends. In the case of a singleton and its dependencies, that won't happen until the container itself is disposed (at least with our ServiceProvider).

Even if you decided to dispose the dependency yourself once you are done using it, the container would keep a reference to the dependency and dispose it again when the container itself is disposed. The same goes for any transitive disposable dependencies.

@tugberkugurlu
Copy link

👍 for throwing.

This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants