jab icon indicating copy to clipboard operation
jab copied to clipboard

Support ability to use existing startup registrations.

Open sake402 opened this issue 2 years ago • 3 comments

In a number of existing application, people already have this.

namespace ABC
{
    public static class ServiceRegistration
    {
        public static void AddXYZ(this IServiceCollection services)
        {
            services.AddScoped<IChatProvider, ChatProvider>();
            services.AddCommunityService<CommunityChatService, CommunityChatThreadModel, CommunityChatMessageModel>();
            services.AddScoped<CommunityChatApplication>()
                .AddScoped<ICommunityApplication>(x => x.GetService<CommunityChatApplication>());
            services.AddServerDataFromPathProvider<CommunityChatThreadModel>();
        }
    }
}

Rather than forcing one to put attribute on tons of classes. I would love the generator to be able to read this existing registration from code and infer registrations from it. This would save a lot of code edits. Of course one may have to decorate the static registration class itself with an attribute so the generator can find it.

If you are open to this idea, I'd love to contribute.

Great software BTW.

sake402 avatar Jan 17 '22 17:01 sake402

Unfortunately supporting the dynamic addition syntax is really hard as the resulting set of services depends on the result of runtime calls.

Take the following example:

public static void AddXYZ(this IServiceCollection services)
{
	if (environment.IsDevelopment())
	{
            services.AddScoped<IChatProvider, ChatProvider>();
	)
	else
	{
            services.AddScoped<IChatProvider, ChatProvider>();
	}
}

Which service should be code generated?

And this is one of the simpler patterns used in IServiceCollection extension methods. Other include multiple levels of nested lambda methods and similar cases that are impossible to evaluate at compile-time.

pakrym avatar Jan 19 '22 23:01 pakrym

Hhm. Didn't really think about such scenario. My other suggestion would be to have the generated service provider take IServiceProvider as constructor overload parameter so that services that are unable to be resolved by the generated are forwarded to the IServiceProvider. This way, they can both coexist aand one will be able to mix such complex registration with with the simple ones.

sake402 avatar Jan 20 '22 06:01 sake402

Having more than one container / service providers has issues with scoping because for example Jab would control instances of scoped and singleton services which IServiceProvider wouldn't be able to resolve. So as soon as you resolved a service from IServiceProvider, everything in the tree from that point would be controlled by the runtime controller. And if any of those resolved services tried to inject a scoped service that Jab had resolved, IServiceProvider would create a new one.

leeoades avatar Mar 26 '22 08:03 leeoades