public static async Task <OperationParserContext> CreateAsync(IReadOnlyList <string> sources)
        {
            var sourceToIndex        = sources.Select((x, i) => new { Index = i, Source = x }).ToDictionary(x => x.Source, x => x.Index);
            var sourceToServiceIndex = await PackageSourceUtility.GetSourceToServiceIndex(sources);

            // This look-up is used to quickly find if a package base address is in one of the source's service indexes.
            var packageBaseAddressToPairs = sourceToServiceIndex
                                            .SelectMany(x => x
                                                        .Value
                                                        .GetServiceEntryUris(ServiceTypes.PackageBaseAddress)
                                                        .Select(u => new { Source = x.Key, ResourceUri = u, PackageBaseAddress = u.AbsoluteUri.TrimEnd('/') + '/' }))
                                            .GroupBy(x => x.PackageBaseAddress)
                                            .ToDictionary(x => x.Key, x => (IReadOnlyList <KeyValuePair <string, Uri> >)x
                                                          .Select(y => new KeyValuePair <string, Uri>(y.Source, y.ResourceUri))
                                                          .ToList());

            // This look-up is used to find all of the sources with a certain package base address. This should
            // normally be a one-to-one mapping, but you can't be too careful...
            var packageBaseAddressToSources = packageBaseAddressToPairs
                                              .ToDictionary(x => x.Key, x => (IReadOnlyList <string>)x.Value.Select(y => y.Key).Distinct().ToList());

            return(new OperationParserContext(
                       sourceToIndex,
                       sourceToServiceIndex,
                       packageBaseAddressToPairs,
                       packageBaseAddressToSources));
        }
예제 #2
0
        public static async Task <Dictionary <Operation, StartRequest> > BuildAsync(IReadOnlyList <string> sources, IEnumerable <Operation> operations)
        {
            var sourceToServiceIndex = await PackageSourceUtility.GetSourceToServiceIndex(sources);

            var packageBaseAddresses = sourceToServiceIndex
                                       .Select(x => x.Value.GetServiceEntryUri(ServiceTypes.PackageBaseAddress).AbsoluteUri.TrimEnd('/') + '/')
                                       .ToList();

            var output = new Dictionary <Operation, StartRequest>();

            foreach (var operation in operations)
            {
                if (output.ContainsKey(operation))
                {
                    continue;
                }

                var packageBaseAddress = packageBaseAddresses[operation.SourceIndex];

                StartRequest request;
                string       id;
                string       version;
                switch (operation.Type)
                {
                case OperationType.PackageBaseAddressIndex:
                    var packageBaseAddressIndex = (OperationWithId)operation;
                    id      = packageBaseAddressIndex.Id.ToLowerInvariant();
                    request = new StartRequest("GET", $"{packageBaseAddress}{id}/index.json");
                    break;

                case OperationType.PackageBaseAddressNupkg:
                    var packageBaseAddressNupkg = (OperationWithIdVersion)operation;
                    id      = packageBaseAddressNupkg.Id.ToLowerInvariant();
                    version = packageBaseAddressNupkg.Version.ToLowerInvariant();
                    request = new StartRequest("GET", $"{packageBaseAddress}{id}/{version}/{id}.{version}.nupkg");
                    break;

                default:
                    throw new NotSupportedException($"The operation type {operation.Type} is not supported.");
                }

                output.Add(operation, request);
            }

            return(output);
        }