Установите пользовательский SessionStore для ConfigureApplicationCook ie без BuildServiceProvider () - PullRequest
2 голосов
/ 25 февраля 2020

У меня есть проект. NET Core 3 (недавно обновленный с 2.2), который использует распределенный кеш Redis и аутентификацию ie.

В настоящее время он выглядит примерно так:

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 (...): предупреждение ASP0000: вызов BuildServiceProvider из кода приложения приводит к дополнительной копии Синглтон сервисы создаются. Рассмотрим альтернативы, такие как сервисы внедрения зависимостей в качестве параметров для «Конфигурирования».

Это не похоже на вариант - ConfigureApplicationCookie находится в Startup.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 должен просто использовать все, что я настроено там.

Как заставить приложение повара ie использовать закачанный магазин?

1 Ответ

2 голосов
/ 25 февраля 2020

Ссылка Использование служб DI для настройки параметров

Если все зависимости вашего пользовательского хранилища являются инъекционными, просто зарегистрируйте свое хранилище и необходимые зависимости в коллекции служб и используйте службы 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 использует именованный экземпляр параметров. - @ KirkLarkin

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

Опция должна включать имя при добавлении его в службы.

...