Skip to content

After migrating to .NET 6 RC 1 No service for type Microsoft.Extensions.Configuration.IConfiguration can be found #36829

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

Closed
marcuslindblom opened this issue Sep 22, 2021 · 9 comments · Fixed by #36832
Assignees
Labels
area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc feature-minimal-hosting ✔️ Resolution: Fixed The bug or enhancement requested in this issue has been checked-in! old-area-web-frameworks-do-not-use *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels
Milestone

Comments

@marcuslindblom
Copy link

In my IServiceCollection extension I have this code.

var serviceProvider = services.BuildServiceProvider();
var configuration = serviceProvider.GetRequiredService<IConfiguration>();

This breaks ofter migrating to .NET 6 using the Program.cs only and no Startup class.
Do I need to register this in my extension as well? How can I make this work for .NET 5 and .NET 6?

@davidfowl
Copy link
Member

davidfowl commented Sep 22, 2021

Why is extension method building the IServiceProvider to get the IConfiguration?

@davidfowl davidfowl added feature-minimal-hosting area-runtime old-area-web-frameworks-do-not-use *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels labels Sep 22, 2021
@marcuslindblom
Copy link
Author

@davidfowl In .NET 5, I thought I needed to?

@marcuslindblom
Copy link
Author

So to be clear, this extension method is in a library I use both in .NET 5 and 6

@davidfowl
Copy link
Member

davidfowl commented Sep 22, 2021

Typically extension methods on IServiceCollection that need IConfiguration take in the user provided configuration via an argument. Building the service provider, builds a temporary throw away service provider and can results in a couple of problems:

  • Multiple singleton instances
  • Not disposing IDisposable services resolved when trying to resolve services from this temporary container.

Calling BuildServiceProvider is an anti-pattern because of those things.

That said, in this particular case of resolving IConfiguration, the side effects are usually fine since the host usually resolves the same singleton instance.

@davidfowl davidfowl self-assigned this Sep 22, 2021
@marcuslindblom
Copy link
Author

Ok, so it's ok to do this but it's an anti-pattern, right?

This is how I use the configuration and the arguments. From a best practice stand point, is it possible to make this code compliant with both .NET 5 and 6?

public static IServiceCollection AddStrife(this IServiceCollection services, Action<DocumentStoreOptions> configureOptions) {

    var serviceProvider = services.BuildServiceProvider();
    var configuration = serviceProvider.GetRequiredService<IConfiguration>();
    services.Configure<DocumentStoreOptions>(options => options.Settings = configuration.GetSection(nameof(DocumentStoreSettings))?.Get<DocumentStoreSettings>()).Configure(configureOptions)

    return services;
}

@davidfowl
Copy link
Member

Like so.

public static IServiceCollection AddStrife(this IServiceCollection services, Action<DocumentStoreOptions> configureOptions)
{
    services.AddOptions<DocumentStoreOptions>()
            .Configure<IConfiguration>((options, configuration) =>
            {
                options.Settings = configuration.GetSection(nameof(DocumentStoreSettings))?.Get<DocumentStoreSettings>();
            })
            .Configure(configureOptions);

    return services;
}

cc @IEvangelist we have a doc for guidance on how to build these sorts of libraries now right?

@marcuslindblom
Copy link
Author

Like so.

public static IServiceCollection AddStrife(this IServiceCollection services, Action<DocumentStoreOptions> configureOptions)
{
    services.AddOptions<DocumentStoreOptions>()
            .Configure<IConfiguration>((options, configuration) =>
            {
                options.Settings = configuration.GetSection(nameof(DocumentStoreSettings))?.Get<DocumentStoreSettings>();
            })
            .Configure(configureOptions);

    return services;
}

cc @IEvangelist we have a doc for guidance on how to build these sorts of libraries now right?

Ok, thanks. Changed my configuration to your proposed solution.

@davidfowl
Copy link
Member

No problem. I'm gonna fix this anyway since it's a compatibility break.

@IEvangelist
Copy link
Member

IEvangelist commented Sep 22, 2021

Like so.

public static IServiceCollection AddStrife(this IServiceCollection services, Action<DocumentStoreOptions> configureOptions)
{
    services.AddOptions<DocumentStoreOptions>()
            .Configure<IConfiguration>((options, configuration) =>
            {
                options.Settings = configuration.GetSection(nameof(DocumentStoreSettings))?.Get<DocumentStoreSettings>();
            })
            .Configure(configureOptions);

    return services;
}

cc @IEvangelist we have a doc for guidance on how to build these sorts of libraries now right?

Yes sir, here you are @davidfowl

✔️ Options pattern guidance for .NET library authors

@davidfowl davidfowl added the ✔️ Resolution: Fixed The bug or enhancement requested in this issue has been checked-in! label Sep 23, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Nov 3, 2021
@amcasey amcasey added area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc and removed area-runtime labels Jun 2, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc feature-minimal-hosting ✔️ Resolution: Fixed The bug or enhancement requested in this issue has been checked-in! old-area-web-frameworks-do-not-use *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants