| File: Metadata\ServiceDescriptorFactory.cs | Web Access |
| Project: src\src\dotnet-svcutil\lib\src\dotnet-svcutil-lib.csproj (dotnet-svcutil-lib) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Linq; namespace Microsoft.Tools.ServiceModel.Svcutil.Metadata { /// <summary> /// This class is intended for caching service descriptors that have already successfully resolved the service metadata. /// This is useful when authentication is required, like in UI-based scenarios. Once metadocs are downloaded they are cached in a service descriptor. /// Observe that it keeps a cache of all created descriptor instances regardless of state; it is intended for short-lived sessions. /// </summary> public class ServiceDescriptorFactory { private IHttpCredentialsProvider _userCredentialsProvider; private IClientCertificateProvider _clientCertificateProvider; private IServerCertificateValidationProvider _serverCertificateValidationProvider; private object _cacheLock = new object(); private Dictionary<int, ServiceDescriptor> _cache = new Dictionary<int, ServiceDescriptor>(); public ServiceDescriptorFactory( IHttpCredentialsProvider userCredentialsProvider, IClientCertificateProvider clientCertificateProvider, IServerCertificateValidationProvider serverCertificateValidationProvider) { _userCredentialsProvider = userCredentialsProvider; _clientCertificateProvider = clientCertificateProvider; _serverCertificateValidationProvider = serverCertificateValidationProvider; } /// <summary> /// Creates a ServiceDescriptor instance or retrieve an existing one that has imported its metadata already. /// </summary> /// <param name="uri"></param> /// <returns></returns> private ServiceDescriptor Get(MetadataDocumentLoader metadaDocLoader) { ServiceDescriptor serviceDescriptor; var key = metadaDocLoader.GetHashCode(); lock (_cacheLock) { if (_cache.ContainsKey(key) && _cache[key].MetadataImported) { serviceDescriptor = _cache[key]; } else { serviceDescriptor = CreateServiceDescriptor(metadaDocLoader); _cache[key] = serviceDescriptor; } } return serviceDescriptor; } protected virtual ServiceDescriptor CreateServiceDescriptor(MetadataDocumentLoader metadaDocLoader) { return new ServiceDescriptor(metadaDocLoader); } protected virtual MetadataDocumentLoader CreateMetadataDocumentLoader(string uri, IHttpCredentialsProvider httpCredentialsProvider, IClientCertificateProvider clientCertificatesProvider, IServerCertificateValidationProvider serverCertificateValidationProvider) { return new MetadataDocumentLoader(uri, httpCredentialsProvider, clientCertificatesProvider, serverCertificateValidationProvider); } protected virtual MetadataDocumentLoader CreateMetadataDocumentLoader(IEnumerable<string> metadataFiles, bool resolveExternalDocuments, IHttpCredentialsProvider httpCredentialsProvider, IClientCertificateProvider clientCertificatesProvider, IServerCertificateValidationProvider serverCertificateValidationProvider) { return new MetadataDocumentLoader(metadataFiles, resolveExternalDocuments, httpCredentialsProvider, clientCertificatesProvider, serverCertificateValidationProvider); } public ServiceDescriptor Get(string metadataUri) { // validate the uri, this would throw if invalid. var metadaDocLoader = CreateMetadataDocumentLoader(metadataUri, _userCredentialsProvider, _clientCertificateProvider, _serverCertificateValidationProvider); return Get(metadaDocLoader); } public ServiceDescriptor Get(IEnumerable<string> metadataFiles) { // validate the uris, this would throw if invalid. var metadaDocLoader = CreateMetadataDocumentLoader(metadataFiles, false, _userCredentialsProvider, _clientCertificateProvider, _serverCertificateValidationProvider); return Get(metadaDocLoader); } /// <summary> /// Purges the cache. Careful use of this method is required: /// This method removes any service descriptor that has not already downloaded its metadata successfully, /// so those currently downloading metadata (if any) will be removed from the cache. /// </summary> public void Purge() { lock (_cacheLock) { var removeKeys = _cache.Keys.Where((k) => !_cache[k].MetadataImported).ToList(); removeKeys.ForEach((k) => _cache.Remove(k)); } } } }