Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support ability to use existing startup registrations. #83

Open
sake402 opened this issue Jan 17, 2022 · 3 comments
Open

Support ability to use existing startup registrations. #83

sake402 opened this issue Jan 17, 2022 · 3 comments

Comments

@sake402
Copy link

sake402 commented Jan 17, 2022

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.

@pakrym
Copy link
Owner

pakrym commented Jan 19, 2022

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.

@sake402
Copy link
Author

sake402 commented Jan 20, 2022

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.

@leeoades
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants