Decorator duplicates lifestyle of decorated instance
See original GitHub issueThe Decorate
method creates a decorator that duplicates the lifestyle of the decorated instance. This means that if a service is a Singleton
, all its decorators will be Singleton
as well. There is currently no way to influence that behavior.
It’s quite common to have the need to register decorators with a lifestyle lower than their decoratees. For instance, even though the decoratee might be a singleton, its decorator might require a dependency on a scoped service (a DbContext for instance). This requires the decorator to have a lifestyle of scoped or transient.
On top of that, in case there are multiple services that apply to a decorator (when multiple registrations for the same service type exist), and those services have different lifestyles, so will the applied decorators. In other words, a registration for a certain decorator could cause different decorator instances to exist with different lifestyles. This could lead to confusion.
Appart from this, the chosen behavior is very different from what (most) DI Containers do. This could lead to confusion as well and perhaps problems when migrating from Scrutor to a custom DI Container or vice versa.
Is there a particular reason for this behavior?
Issue Analytics
- State:
- Created 6 years ago
- Reactions:3
- Comments:19 (10 by maintainers)
Top GitHub Comments
Ah, I see. What you are saying is that giving the decorator a shorter lifetime than its decoratee, might cause the decorator to become a Captive Dependency when injected into a consumer.
This is absolutely correct, but on the other hand, as we discussed above, keeping the decorator’s lifestyle in sync with that of its decoratee will cause Captive Dependencies as well, in case the decorator takes a dependency on other services (other than the decoratee) that have a shorter lifetime than the decoratee.
The difference is, by making the decorator’s lifestyle fixing to that of its decoratee, it will be impossible for the user to fix a Captive Dependency when it occurs, while when it occurs with the configurable lifestyle, we actually have the ability to fix the problem.
That said, in either case, it is important to have some tooling that detects Captive Dependencies for us. Both Microsoft.Extensions.DependencyInjection, Autofac, Castle Windsor and Simple Injector do detect these problems (although with MS you will have to explicitly configure the container to do so).
Do you mean you think I’m advocating against “having multiple registrations for the same service, with different lifestyles”? My text might have been confusing, but I’m actually not advocating against this. In my experience this is a really common use case and all DI containers (that I know of) do support this.
I would really vote to add this behavior, and further make transient the default lifestyle for a decorator, or make the overloads more explicit, i.e.
DecorateTransient
,DecorateScoped
andDecorateSingleton
.