async Task <T> IAsyncConverter <AzureSearchAttribute, T> .ConvertAsync(AzureSearchAttribute input, CancellationToken cancellationToken)
            {
                if (IsEmpty(input.Key))
                {
                    throw new InvalidOperationException(
                              $"Must provide a valid {nameof(AzureSearchAttribute.Key)} in order to resolve {typeof(T).Name}");
                }

                try
                {
                    return(await _owner.SearchIndexClientInput(input).Documents.GetAsync <T>(input.Key, cancellationToken: cancellationToken));
                }
                catch (Exception)
                {
                    return(default);
        private ISearchIndexClient SearchIndexClientInput(AzureSearchAttribute input)
        {
            string GenerateKey() => $"{input.SearchServiceName}_{input.ApiKey}";

            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug(
                    $"Resolving {nameof(ISearchIndexClient)}, AzureSearch:(Service:{input.SearchServiceName}, Index:{input.IndexName})");
            }

            var searchServiceClient = _cacheService.GetOrAdd(
                key: GenerateKey(),
                addItemFactory: () =>
                new SearchServiceClient(input.SearchServiceName, new SearchCredentials(input.ApiKey)));


            return(searchServiceClient.Indexes.GetClient(input.IndexName));
        }
        private static void ValidateAttribute(AzureSearchAttribute input, Type _)
        {
            string Invalid(string propName) =>
            $"{propName} must be provided either by AppSettings or {nameof(AzureSearchAttribute)}";

            if (IsEmpty(input.SearchServiceName))
            {
                throw new InvalidOperationException(Invalid(nameof(AzureSearchAttribute.SearchServiceName)));
            }

            if (IsEmpty(input.ApiKey))
            {
                throw new InvalidOperationException(Invalid(nameof(AzureSearchAttribute.ApiKey)));
            }

            if (IsEmpty(input.IndexName))
            {
                throw new InvalidOperationException(Invalid(nameof(AzureSearchAttribute.IndexName)));
            }
        }
 public Task <IAsyncCollector <T> > ConvertAsync(AzureSearchAttribute input, CancellationToken _) =>
 Task.FromResult <IAsyncCollector <T> >(
     new DocumentCollector <T>(
         _owner.SearchIndexClientInput(input),
         _owner._logger));