dadhi / DryIoc

DryIoc is fast, small, full-featured IoC Container for .NET
MIT License
982 stars 122 forks source link

Check for mismatch lifestyle scope between service and dependencies #633

Open TheHunter opened 4 months ago

TheHunter commented 4 months ago

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.

dadhi commented 4 months ago

@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().

TheHunter commented 4 months ago

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.

dadhi commented 4 months ago

Huh, ok. Then what services do you mark with this new rule, the Transients or the consuming Scoped ones?

TheHunter commented 3 months ago

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

dadhi commented 3 months ago

@TheHunter Yes, it kinda makes sense because we already have Setup.TrackDisposableTransient, Setup.AllowDisposableTransient

TheHunter commented 3 months ago

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 commented 3 months ago

@dadhi Yeah, I went to other stuff in meanwhile. I will look into this soon.