Асинхронные накладные расходы Asp.Net Core Identity в пользовательских хранилищах

При разработке основного веб-приложения Asp.Net мне нужно было добавить в свой проект идентификацию Asp.Net Core. Однако мне нужна была лишь небольшая часть Identity, потому что, например. Я знаю, что это приложение никогда не позволит сторонним входам в систему. Поэтому я решил написать свои пользовательские магазины. При поиске в Интернете хороших решений о том, как это сделать, я часто видел такую ​​реализацию:

    public Task SetUserNameAsync(ApplicationUser user, string userName, CancellationToken cancellationToken)
    {
        cancellationToken.ThrowIfCancellationRequested();

        if (user == null)
            throw new ArgumentNullException(nameof(user));

        if(string.IsNullOrWhiteSpace(userName))
            throw new ArgumentNullException(nameof(userName));

        user.Username = userName;

        return Task.CompletedTask;
    }

or

    public Task<string> GetUserNameAsync(ApplicationUser user, CancellationToken cancellationToken)
    {
        cancellationToken.ThrowIfCancellationRequested();

        if (user == null)
            throw new ArgumentNullException(nameof(user));

        return Task.FromResult(user.Username);
    }

насколько я понимаю Это будет называться примерно так:

var user = await store.GetUserNameAsync(_user, CancellationToken.None);

но разве это не создаст State Mashine для геттера/сеттера, который должен просто немедленно вернуться без каких-либо больших накладных расходов, или есть ли какая-то хорошая польза от этого, которую я не вижу прямо сейчас?


person Brezelmann    schedule 20.10.2018    source источник


Ответы (1)


Identity — это фреймворк с широкими возможностями настройки. Например. вы можете создать свой собственный UserManager, все еще используя стандартный SignInManager, который обрабатывает вход в систему, выход из системы, ...

То, что вы нашли, похоже, является реализацией UserManager.GetUserNameAsync()> https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.identity.usermanager-1.getusernameasync?view=aspnetcore-2.1

Причина, по которой этот метод возвращает задачу, заключается в том, что реализация может потребовать доступ к базе данных или сети.

Если вы действительно не хотите использовать что-либо из Identity и делать все самостоятельно, нет необходимости возвращать задачу. Но на всякий случай я бы посоветовал дважды подумать, хороший ли это подход.

person Christoph Lütjen    schedule 20.10.2018
comment
Я понимаю, откуда вы, однако, почему я должен использовать доступ к БД в моем магазине в геттере/сеттере (если это действительно только геттер/сеттер), если я могу просто вызвать метод UpdateAsync для распространения изменений, например, имя пользователя моего пользователя. И просто для уточнения я хочу использовать Identity только не все функции, потому что я знаю, что некоторые из них мне не нужны. - person Brezelmann; 20.10.2018
comment
Не уверен, что понял вашу мысль. Да, GetuserNameAsync просто у меня есть объект пользователя, и я хочу получить значение, которое я должен использовать в качестве имени пользователя. (может быть значение свойства Username или Email или результат чего-то вроде mydb.GetUserNameFor(user.Id). UserManager.UpdateAsync предназначен для обновления пользователя в вашей базе данных, поэтому что-то совершенно другое. - person Christoph Lütjen; 20.10.2018
comment
Я пытаюсь уточнить. если у меня есть мой GetUserNameAsync, и я даю ему свой объект ApplicationUser, откуда я хочу, чтобы значение позволяло сказать имя пользователя. Почему я должен помечать это как асинхронный и давать кому-то возможность подождать. Есть ли такой пример в реальном мире, где мне нужно было бы выполнять асинхронные операции, особенно если у меня есть класс ApplicationUser, в котором установлены все его значения? Конечно, я мог бы пойти в свою БД и получить нового ApplicationUser, чтобы прочитать значение, но если у меня есть ApplicationUser со всеми значениями, зачем мне это делать? - person Brezelmann; 20.10.2018
comment
Как вы написали, в большинстве случаев здесь нет необходимости выполнять асинхронную операцию. Но поскольку GetUserNameAsync является частью большого фреймворка, нам нужен ОДИН определенный метод, который могут использовать другие классы, а другие настройки теоретически могут потребовать поиска здесь в БД. Только если у нас всегда одна и та же подпись, другие классы фреймворка могут использовать этот метод. И из-за этого «для других настроек может потребоваться асинхронность», эта ОДНА подпись является асинхронной. Имейте в виду, что накладные расходы очень малы. - person Christoph Lütjen; 20.10.2018
comment
Ок, спасибо за разъяснение. Я просто немного волновался, потому что я думал, что где-то читал, что накладные расходы на создание этой в моем случае бесполезной машины состояния при вызове GetUserNameAsync были довольно большими. - person Brezelmann; 20.10.2018
comment
Возможно, это не лучший тест, но просто в качестве примера (первый результат Google, который я нашел): мы говорим о 0,0016 мс. (1582 мс для 1 000 000 вызовов и сам вызов функции включены): stackoverflow.com /questions/23871806/async-ожидание-производительность - person Christoph Lütjen; 21.10.2018