| File: TemplateSearchCoordinator.cs | Web Access |
| Project: src\sdk\src\TemplateEngine\Microsoft.TemplateSearch.Common\Microsoft.TemplateSearch.Common.csproj (Microsoft.TemplateSearch.Common) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.Extensions.Logging; using Microsoft.TemplateEngine.Abstractions; using Microsoft.TemplateSearch.Common.Abstractions; namespace Microsoft.TemplateSearch.Common { /// <summary> /// <see cref="TemplateSearchCoordinator"/> performs the search for the templates in registered search providers. /// </summary> public sealed class TemplateSearchCoordinator { private readonly IEngineEnvironmentSettings _environmentSettings; private readonly IReadOnlyDictionary<string, ITemplateSearchProvider> _providers; public TemplateSearchCoordinator( IEngineEnvironmentSettings environmentSettings, IReadOnlyDictionary<string, Func<object, object>>? additionalDataReaders = null) { _environmentSettings = environmentSettings ?? throw new ArgumentNullException(nameof(environmentSettings)); IReadOnlyDictionary<string, Func<object, object>> additionalDataReaders1 = additionalDataReaders ?? new Dictionary<string, Func<object, object>>(); Dictionary<string, ITemplateSearchProvider> configuredProviders = new Dictionary<string, ITemplateSearchProvider>(); foreach (ITemplateSearchProviderFactory factory in _environmentSettings.Components.OfType<ITemplateSearchProviderFactory>()) { configuredProviders.Add(factory.DisplayName, factory.CreateProvider(_environmentSettings, additionalDataReaders1)); } _providers = configuredProviders; } /// <summary> /// Searches for the templates matching the filters in registered search providers. /// </summary> /// <param name="packFilter">The filter that defines if <see cref="TemplatePackageSearchData"/> is a match.</param> /// <param name="matchingTemplatesFilter">The filter that list of templates that are the match inside given <see cref="TemplatePackageSearchData"/>.</param> /// <param name="cancellationToken">The cancellation token to cancel the operation.</param> /// <returns>The list of <see cref="SearchResult"/> representing the result of the search for given <see cref="ITemplateSearchProvider"/>.</returns> public async Task<IReadOnlyList<SearchResult>> SearchAsync( Func<TemplatePackageSearchData, bool> packFilter, Func<TemplatePackageSearchData, IReadOnlyList<ITemplateInfo>> matchingTemplatesFilter, CancellationToken cancellationToken) { if (packFilter is null) { throw new ArgumentNullException(nameof(packFilter)); } if (matchingTemplatesFilter is null) { throw new ArgumentNullException(nameof(matchingTemplatesFilter)); } cancellationToken.ThrowIfCancellationRequested(); List<SearchResult> results = new List<SearchResult>(); foreach (ITemplateSearchProvider provider in _providers.Values) { try { var providerResults = await provider.SearchForTemplatePackagesAsync(packFilter, matchingTemplatesFilter, cancellationToken).ConfigureAwait(false); results.Add(new SearchResult(provider, true, hits: providerResults)); } catch (TaskCanceledException) { throw; } catch (Exception ex) { _environmentSettings.Host.Logger.LogDebug("Search by provider {0} failed, details: {1}", provider.Factory.DisplayName, ex); results.Add(new SearchResult(provider, false, ex.Message)); } } return results; } } }