// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Net.Http; using System.Net.Http.Formatting; using System.Web.Http.Controllers; using System.Web.Http.Description; using System.Web.Http.Dispatcher; using System.Web.Http.Filters; using System.Web.Http.Metadata; using System.Web.Http.ModelBinding; using System.Web.Http.Properties; using System.Web.Http.Services; using System.Web.Http.Tracing; using System.Web.Http.Validation; using System.Web.Http.ValueProviders; namespace System.Web.Http { /// /// This provides a centralized list of type-safe accessors describing where and how we get services. /// This also provides a single entry point for each service request. That makes it easy /// to see which parts of the code use it, and provides a single place to comment usage. /// Accessors encapsulate usage like: /// /// Type-safe using {T} instead of unsafe . /// which type do we key off? This is interesting with type hierarchies. /// do we ask for singular or plural? /// is it optional or mandatory? /// what are the ordering semantics /// /// Expected that any we return is non-null, although possibly empty. /// [EditorBrowsable(EditorBrowsableState.Never)] public static class ServicesExtensions { /// /// Get ValueProviderFactories. The order of returned providers is the priority order that we search the factories. /// public static IEnumerable GetValueProviderFactories(this DefaultServices services) { return services.GetServices(); } /// /// Get a controller selector, which selects an given an . /// public static IHttpControllerSelector GetHttpControllerSelector(this DefaultServices services) { return services.GetServiceOrThrow(); } /// /// Controller activator is used to instantiate an . /// /// /// An instance or null if none are registered. /// public static IHttpControllerActivator GetHttpControllerActivator(this DefaultServices services) { return services.GetServiceOrThrow(); } public static IAssembliesResolver GetAssembliesResolver(this DefaultServices services) { return services.GetServiceOrThrow(); } public static IHttpControllerTypeResolver GetHttpControllerTypeResolver(this DefaultServices services) { return services.GetServiceOrThrow(); } public static IHttpActionSelector GetActionSelector(this DefaultServices services) { return services.GetServiceOrThrow(); } public static IHttpActionInvoker GetActionInvoker(this DefaultServices services) { return services.GetServiceOrThrow(); } public static IApiExplorer GetApiExplorer(this DefaultServices services) { return services.GetServiceOrThrow(); } public static IDocumentationProvider GetDocumentationProvider(this DefaultServices services) { return services.GetService(); } public static IEnumerable GetFilterProviders(this DefaultServices services) { return services.GetServices(); } public static ModelMetadataProvider GetModelMetadataProvider(this DefaultServices services) { return services.GetServiceOrThrow(); } public static IEnumerable GetModelBinderProviders(this DefaultServices services) { return services.GetServices(); } public static IEnumerable GetModelValidatorProviders(this DefaultServices services) { return services.GetServices(); } public static IContentNegotiator GetContentNegotiator(this DefaultServices services) { return services.GetService(); } public static IActionValueBinder GetActionValueBinder(this DefaultServices services) { return services.GetService(); } public static ITraceManager GetTraceManager(this DefaultServices services) { return services.GetService(); } public static ITraceWriter GetTraceWriter(this DefaultServices services) { return services.GetService(); } public static IBodyModelValidator GetBodyModelValidator(this DefaultServices services) { return services.GetService(); } // Runtime code shouldn't call GetService() directly. Instead, have a wrapper (like the ones above) and call through the wrapper. private static TService GetService(this DefaultServices services) { if (services == null) { throw Error.ArgumentNull("services"); } return (TService)services.GetService(typeof(TService)); } private static IEnumerable GetServices(this DefaultServices services) { if (services == null) { throw Error.ArgumentNull("services"); } return services.GetServices(typeof(TService)).Cast(); } private static T GetServiceOrThrow(this DefaultServices services) { T result = services.GetService(); if (result == null) { throw Error.InvalidOperation(SRResources.DependencyResolverNoService, typeof(T).FullName); } return result; } } }