Aspnetcore.docs: Data Protection - Provide IXmlRepository with singleton dependencies

Created on 7 Apr 2020  Â·  7Comments  Â·  Source: dotnet/AspNetCore.Docs

In a .NET Core 3.1 project, one may configure Data Protection in ConfigureServices like below:

public void ConfigureServices(IServiceCollection services)
{
    // ...

    var sp = services.BuildServiceProvider();
    services.AddDataProtection()
            .AddKeyManagementOptions(o => o.XmlRepository = sp.GetService<IXmlRepository>());
}

This raises below warning (which makes sense):

Calling 'BuildServiceProvider' from application code results in an additional copy of singleton services being created. Consider alternatives such as dependency injecting services as parameters to 'Configure'.

I'm using a service provider there because my implementation of IXmlRepository has a dependency to a singleton service.

What would be the recommended way of providing my IXmlRepository implementation without having to build the service provider (and thus making additional copies of singleton services)?


Document Details

⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

Security-PU Source - Docs.ms doc-enhancement

Most helpful comment

I had this problem too because MyDataStore is a singleton, inspired by EF implementation I managed to do this:

C# services.AddDataProtection().Services.AddSingleton<IConfigureOptions<KeyManagementOptions>>(serv => { return new ConfigureOptions<KeyManagementOptions>(options => { options.XmlRepository = new MyXmlRepository(serv.GetService<IMyDataStore>()); }); });

All 7 comments

I am having the same issue with this trying to call services.BuildServiceProvider().GetDataProtectionProvider(). What is the correct way to inject it ?

public void ConfigureServices(IServiceCollection services)
{
      services.AddControllers();

      services.AddDataProtection();

      var dpp = services.BuildServiceProvider().GetDataProtectionProvider();

      services.AddSingleton<IDataProtectionProvider>(dpp);
}

It looks like the EF Core persistence support created a wrapper that creates temporary scopes. See here . That nuget package actually eliminated our need for any of our custom stuff.

I had this problem too because MyDataStore is a singleton, inspired by EF implementation I managed to do this:

C# services.AddDataProtection().Services.AddSingleton<IConfigureOptions<KeyManagementOptions>>(serv => { return new ConfigureOptions<KeyManagementOptions>(options => { options.XmlRepository = new MyXmlRepository(serv.GetService<IMyDataStore>()); }); });

@Tratcher or @davidfowl , can you suggest the recommendations here?

@stefanb05's answer is good.

We added more convenient helpers for this:

C# services.AddOptions<KeyManagementOptions>() .Configure<IMyDataStore>((options, store) => { options.XmlRepository = new MyXmlRepository(store); });

It removes the clunky calls to GetService and hides IConfigureOptions<T>

Doesn't that use an odd lifetime?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sonichanxiao picture sonichanxiao  Â·  3Comments

royshouvik picture royshouvik  Â·  3Comments

Rick-Anderson picture Rick-Anderson  Â·  3Comments

YeyoCoder picture YeyoCoder  Â·  3Comments

serpent5 picture serpent5  Â·  3Comments