DryIoc
DryIoc copied to clipboard
Check for mismatch lifestyle scope between service and dependencies
Hi all, I'm facing with a issue in my code, when I want to check "scopes" between a service and its dependencies, take a this example:
public class MyService : IMyService {}
public interface IMyService {}
public class RootService(IMyService myService) : IRootService
{
public IMyService Service { get; } = myService;
}
public interface IRootService
{
IMyService Service { get; }
}
then:
IContainer container = new Container();
container.Register<IMyService, MyService>(Reuse.Transient);
container.Register<IRootService, RootService>(Reuse.Singleton);
var service = container.Resolve<IRootService>();
The resolution of IRootService doesn't throw an exception, and I'm wondering if there's a way to check this mismatch of scopes between "root service" and "root dependency".
Thank you in advance.
@TheHunter By default it is fine to have Transient for any kind of Scoped consumer. Because Transient means that service is likely stateless and can be recreated whenever it needed.
You may alter this behavior via Rules.WithThrowIfScopedOrSingletonHasTransientDependency()
.
hi @dadhi, thank you for your suggestion, but It seems it's only possible to use rules on IContainer instance, so as a global rule for all registrations in the container, but not for single registration, right?
It would be worth to turn on this rule (WithThrowIfScopedOrSingletonHasTransientDependency) only for some services, what do you think about it?
In my case, we apply some strong rules for lifestyles dependencies, but only for external registrations, so for them we would turn off the default rule.
Huh, ok. Then what services do you mark with this new rule, the Transients or the consuming Scoped ones?
Hi @dadhi, I think the Transient ones, in general I think only the dependencies should be marked, in order to turn on the rule "WithThrowIfScopedOrSingletonHasTransientDependency".
In fact, i think something like this could be resolved this situation:
IContainer container = new Container();
container.Register<IMyService, MyService>(Reuse.Transient, reuse: Rules.WithThrowIfScopedOrSingletonHasTransientDependency());
container.Register<IRootService, RootService>(Reuse.Singleton);
var service = container.Resolve<IRootService>();
What do you think about?
Sorry for this delay on this response
@TheHunter Yes, it kinda makes sense because we already have Setup.TrackDisposableTransient
, Setup.AllowDisposableTransient
Hi @dadhi , do you think It would be possible to implement the overload as proposed ?
Or if you have other suggestion, It would be appreciated.
Thanks in advance.
@dadhi Yeah, I went to other stuff in meanwhile. I will look into this soon.