Есть ли в UserManager ‹IdentityUser› кеш?

У меня есть приложение, которое использует Microsoft.AspNetCore.Identity.UserManager для управления пользователями. Использую ядро ​​2.2. UserManager внедряется с помощью встроенной инъекции зависимостей в мои службы (не мной). нравится:

public MyService(UserManager<IdentityUser> userManager)
{
   _userManager = userManager;
}

Когда я впервые пытаюсь получить пользователя по идентификатору (FindByIdAsync), я вижу в консоли запрос к базе данных. Следующие запросы с тем же идентификатором. Я не вижу никаких запросов к db, но приложение работает и получил пользователя.

В Startup.cs у меня нет конфигурации для userManager. Я просто использую метод расширения:

public void ConfigureServices(IServiceCollection services)
        {
            services
                .AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                Configuration.GetConnectionString("MyConnectionString"));
            services
                .AddIdentity<IdentityUser, IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
            services.AddMvc();
            var configService = new ConfigurationService(Configuration);
            services
                .AddIdentityServer()
                .AddDeveloperSigningCredential()
                .AddInMemoryApiResources(configService.GetApiResources())
                .AddInMemoryClients(configService.GetClients())
                .AddTestUsers(configService.GetUsers());
        }

Вопрос: Может, есть способ настроить эту функцию кеширования в UserManager? Укажите мне, где можно получить информацию о том, как долго хранится этот кеш.


person Alexandr    schedule 26.03.2019    source источник
comment
Вы проверили ответы на этот вопрос?   -  person Matt.G    schedule 26.03.2019
comment
Возможный дубликат UserManager ASP.NET Identity кэширует пользователей?   -  person Spotted    schedule 26.03.2019
comment
@ Matt.G да, они установили экземпляр диспетчера пользователей с Unity. Я использую диспетчер пользователей из коробки, созданный для меня фреймворком.   -  person Alexandr    schedule 26.03.2019


Ответы (1)


Я покопался в исходном коде Identity на Github и закончил UserStore:

public override Task<TUser> FindByIdAsync(string userId, CancellationToken cancellationToken = default(CancellationToken))
{
    cancellationToken.ThrowIfCancellationRequested();
    ThrowIfDisposed();
    var id = ConvertIdFromString(userId);
    return UsersSet.FindAsync(new object[] { id }, cancellationToken);
}

UsersSet Имея тип DbSet<TUser>, Identity не имеет возможности напрямую управлять кэшированием, но полагается на внутренние компоненты EF.

Покопавшись в исходном коде EF, я закончил DbContext:

object IDbSetCache.GetOrAddSet(IDbSetSource source, Type type)
{
    CheckDisposed();

    if (_sets == null)
    {
        _sets = new Dictionary<Type, object>();
    }

    if (!_sets.TryGetValue(type, out var set))
    {
        set = source.Create(this, type);
        _sets[type] = set;
    }

    return set;
}

и похоже, что есть механизм кэширования, поддерживаемый простым и понятным Dictionary.

Однако, как указал Мэтт Г. в своем комментарии, решение для управления кешированием лежит на уровне выше вашего сервиса: оно связано с тем, как вы управляете своей областью зависимостей при внедрении UserManager.

person Spotted    schedule 26.03.2019
comment
Я его не закачиваю, мне его закачивает встроенный DI. - person Alexandr; 26.03.2019
comment
@Alexandr Можете ли вы отредактировать свой вопрос с помощью кода, устанавливающего инъекцию? - person Spotted; 26.03.2019
comment
нет кода, который настраивает внедрение для UserManager. Обновлено - person Alexandr; 26.03.2019
comment
@Spotted, вызывающий код вызывает FindAsync метод поиска EntityFrameworks, который будет работать, проверяя коллекцию отслеживаемых объектов перед обращением к базе данных. - person johnny 5; 26.03.2019