ICredentialProvider в сочетании с DbContext BotFramework v4 - PullRequest
0 голосов
/ 21 ноября 2018

Я использую MultiCredentialProvider, который реализует интерфейс Microsoft.Bot.Connector.Authentication.ICredentialProvider.Он работает со статическими значениями , но как только я пытаюсь передать хранилище, которое использует DbContext для получения учетных данных моих ботов, происходит сбой со следующим сообщением.

System.InvalidOperationException: An attempt was made to use the context while it is being configured. A DbContext instance cannot be used inside OnConfiguring since it is still being configured at this point. This can happen if a second operation is started on this context before a previous operation completed. Any instance members are not guaranteed to be thread safe.

Это вызвано тем, что хранилище должно быть ограничено, а не просто передано объекту для использования на более поздней стадии.Хранилище разрешается методом ConfigureServices класса Startup.

var sp = services.BuildServiceProvider();
var repository = sp.GetService<SomeRepository>();

services.AddBot<SomeBot>(options => { 
         options.CredentialProvider = new MultiCredentialProvider(configuration, repository); 
    })

Вопрос в том, как разрешить службу по требованию, чтобы избежать этой ошибки?Можно ли разрешить весь CredentialProvider, чтобы я мог использовать инъекцию конструктора?Что-нибудь еще, чего мне здесь не хватает?

-

Обновление: В качестве временного решения я сначала получаю список учетных данных из базы данных, затем создаю объект и передаю учетные данные в MultiCredentialProvider конструктор.Единственная проблема заключается в том, что все назначается при запуске и не может быть изменено позднее.Все еще ищем лучшие решения.

1 Ответ

0 голосов
/ 17 апреля 2019

В итоге я написал Func, который вызывается, когда требуются учетные данные.Значения кэшируются, поэтому это не дорогой поиск.

public class MultiCredentialProvider : ICredentialProvider
    {
        private readonly IConfiguration _configuration;
        private readonly Func<Task<List<MultiBotCredential>>> _botCredentialsFunc;

        public MultiCredentialProvider(IConfiguration configuration, Func<Task<List<MultiBotCredential>>> botCredentialsFunc)
        {
            _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
            _getBotCredentialsFunc = botCredentialsFunc;
        }

        public int BotId => _configuration.GetBotId();

        public async Task<bool> IsValidAppIdAsync(string appId)
        {
            var botCredentials = await _botCredentialsFunc.Invoke();
            var credential = botCredentials.FirstOrDefault(x => x.BotId == BotId);

            if (credential == null)
            {
                return false;
            }

            return credential.AppId.Equals(appId, StringComparison.InvariantCultureIgnoreCase);
        }

        ...
    }
...