// 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;
}
}
}