asp.net-core - 在没有 BuildServiceProvider() 的情况下为 ConfigureApplicationCookie 设置自定义 SessionStore

标签 asp.net-core .net-core dependency-injection stackexchange.redis cookie-authentication

我有一个使用 Redis 分布式缓存和 cookie 身份验证的 .NET Core 3 项目(最近从 2.2 升级)。

它目前看起来像这样:

public void ConfigureServices(IServiceCollection services)
{
    // Set up Redis distributed cache
    services.AddStackExchangeRedisCache(...);

    ...

    services.ConfigureApplicationCookie(options =>
    {
        ...
        // Get a service provider to get the distributed cache set up above
        var cache = services.BuildServiceProvider().GetService<IDistributedCache>();

         options.SessionStore = new MyCustomStore(cache, ...);
    }):
}

问题是BuildServiceProvider()导致构建错误:

Startup.cs(...): warning ASP0000: 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'.



这似乎不是一个选项 - ConfigureApplicationCookieStartup.ConfigureServices并且只能配置新服务,Startup.Configure可以使用新服务,但不能覆盖 CookieAuthenticationOptions.SessionStore成为我的定制商店。

我试过添加 services.AddSingleton<ITicketStore>(p => new MyCustomRedisStore(cache, ...))之前 ConfigureApplicationCookie ,但这被忽略了。

显式设置 CookieAuthenticationOptions.SessionStore似乎是让它使用本地内存存储以外的任何东西的唯一方法。

我在网上找到的示例 BuildServiceProvider() ;

理想情况下,我想做类似的事情:

services.ConfigureApplicationCookieStore(provider => 
{
    var cache = provider.GetService<IDistributedCache>();
    return new MyCustomStore(cache, ...);
});

或者

public void Configure(IApplicationBuilder app, ... IDistributedCache cache)
{
    app.UseApplicationCookieStore(new MyCustomStore(cache, ...));
}

然后CookieAuthenticationOptions.SessionStore应该只使用我在那里配置的任何内容。

如何让应用程序 cookie 使用注入(inject)的存储?

最佳答案

引用 Use DI services to configure options

如果您的自定义商店的所有依赖项都是可注入(inject)的,那么只需在服务集合中注册您的商店和所需的依赖项,并使用 DI 服务来配置选项

public void ConfigureServices(IServiceCollection services) {
    // Set up Redis distributed cache
    services.AddStackExchangeRedisCache(...);

    //register my custom store
    services.AddSingleton<ITicketStore, MyCustomRedisStore>();

    //...

    //Use DI services to configure options
    services.AddOptions<CookieAuthenticationOptions>(IdentityConstants.ApplicationScheme)
        .Configure<ITicketStore>((options, store) => {
            options.SessionStore = store;
        });

    services.ConfigureApplicationCookie(options => {
        //do nothing
    }):
}

如果没有,则解决实际注册的内容

例如
//Use DI services to configure options
services.AddOptions<CookieAuthenticationOptions>(IdentityConstants.ApplicationScheme)
    .Configure<IDistributedCache>((options, cache) => {
        options.SessionStore = new MyCustomRedisStore(cache, ...);
    });

笔记:

ConfigureApplicationCookie uses a named options instance. - @KirkLarkin


public static IServiceCollection ConfigureApplicationCookie(this IServiceCollection services, Action<CookieAuthenticationOptions> configure)
        => services.Configure(IdentityConstants.ApplicationScheme, configure);

该选项在将其添加到服务时需要包含名称。

关于asp.net-core - 在没有 BuildServiceProvider() 的情况下为 ConfigureApplicationCookie 设置自定义 SessionStore,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60394376/

相关文章:

javascript - 无法将 json 转换为 javascript 中谷歌图表所需的格式

c# - Visual Studio 和 ASP.NET Core 中的 ssl 问题

angular - 如何修改 csproj PublishRunWebpack 以包含来自外部目录的静态文件

c# - .net 核心中的 httprequest.UserHostName

.net-core - FluentMigrator 两个 SQL 数据库

.net-core - 带有 dotnet 核心的 Parceljs

android - 在不同的 Activity 中注入(inject) ViewModelFactory

c# - 我应该在 MSAL.NET 中使用什么类型的 ApplicationBuilder?我正在使用 ASP.NET Core Web Api

design-patterns - 如何向一个 5 岁的 child 解释依赖注入(inject)?

c# - 配置 autofac 容器