khellang / Scrutor

Assembly scanning and decoration extensions for Microsoft.Extensions.DependencyInjection
MIT License
3.63k stars 239 forks source link

Question: What is the 'correct' technique to use when the Lifetime needs to vary for each type/instance being registered? #177

Open bhehe opened 2 years ago

bhehe commented 2 years ago

Currently we're using Scrutor to scan & register a set of components and use the approach below:

            services.Scan(scan =>
                scan.FromAssemblies(assembliesToScan)
                    .AddClasses(classes => classes.Where(type => typeFilter(type) && IsService(type)))
                    .AsSelfWithInterfaces()
                    .WithScopedLifetime());

I'm looking for the 'correct' way to replace the .WithScopedLifetime() call to be conditional by inspecting each matching type for an attribute where I can indicate the lifetime to use and if that attribute is not present, use a default instead.

I've looked into [ServiceDescriptorAttribute] but it has a 1st argument of Type which I don't really want to alter the behavior and want it to remain based on the calls from the scan fluent chain (.AsSelfWithInterfaces() from above). I only want to alter the lifetime that is used AND to not require this attribute to be present and when not present apply a default lifetime.

I'd also like to be able to use "my attributes" versus tightly coupling all my components to Scrutor directly but that's just a preference.

I know there's the .WithLifetime(..) option and I could provide my own function but what I don't have is a way to inspect each type in that method as it doesn't use a Func<Type, Lifetime> to support that approach.

So given the current version, what's the best option to achieve this goal? As for any feature request to support this, it seems like if WithLifetime(..) would accept that function to support inspecting each type that would get me very close to my goal and not require me decorating all my code with Scrutor specific attributes.

khellang commented 2 years ago

Hi @bhehe! 👋

Unfortunately I don't think there's a good way to accomplish this today, but I'd be happy to take a PR for your proposed overload ☺️