/// <summary> /// Select a controller. The <paramref name="request"/> parameter is guaranteed not to be <c>null</c>. /// </summary> /// <param name="request"></param> /// <returns></returns> protected virtual HttpControllerDescriptor OnSelectController(HttpRequestMessage request) { ControllerIdentification controllerName = this.GetControllerIdentificationFromRequest(request); if (String.IsNullOrEmpty(controllerName.Name)) { throw new HttpResponseException(request.CreateResponse(HttpStatusCode.NotFound)); } HttpControllerDescriptor controllerDescriptor; if (this._controllerInfoCache.Value.TryGetValue(controllerName, out controllerDescriptor)) { return(controllerDescriptor); } ICollection <Type> matchingTypes = this._controllerTypeCache.GetControllerTypes(controllerName); // ControllerInfoCache is already initialized. Contract.Assert(matchingTypes.Count != 1); if (matchingTypes.Count == 0) { // no matching types throw ApiControllerNotFoundException.Create(controllerName); } // multiple matching types throw AmbigiousApiRequestException.Create(controllerName, request.GetRouteData().Route, matchingTypes); }
private ConcurrentDictionary <ControllerIdentification, HttpControllerDescriptor> InitializeControllerInfoCache() { // let's find and cache the found controllers var result = new ConcurrentDictionary <ControllerIdentification, HttpControllerDescriptor>(ControllerIdentification.Comparer); var duplicateControllers = new HashSet <ControllerIdentification>(); Dictionary <ControllerIdentification, ILookup <string, Type> > controllerTypeGroups = this._controllerTypeCache.Cache; foreach (var controllerTypeGroup in controllerTypeGroups) { ControllerIdentification controllerName = controllerTypeGroup.Key; foreach (var controllerTypesGroupedByNs in controllerTypeGroup.Value) { foreach (Type controllerType in controllerTypesGroupedByNs) { if (result.Keys.Contains(controllerName)) { duplicateControllers.Add(controllerName); break; } result.TryAdd(controllerName, new HttpControllerDescriptor(this._configuration, controllerName.Name, controllerType)); } } } foreach (ControllerIdentification duplicateController in duplicateControllers) { HttpControllerDescriptor descriptor; result.TryRemove(duplicateController, out descriptor); } return(result); }
public HttpControllerDescriptor SelectController(HttpRequestMessage request) { if (request == null) { throw new ArgumentNullException("request"); } ControllerIdentification controllerName = this.GetControllerIdentificationFromRequest(request); if (String.IsNullOrEmpty(controllerName.Name)) { throw new HttpResponseException(request.CreateResponse(HttpStatusCode.NotFound)); } if (controllerName.Version == null) { controllerName.Version = this.GetVersionRouteDefaults(request); } HttpControllerDescriptor controllerDescriptor; if (this._controllerInfoCache.Value.TryGetValue(controllerName, out controllerDescriptor)) { return(controllerDescriptor); } ICollection <Type> matchingTypes = this._controllerTypeCache.GetControllerTypes(controllerName); // ControllerInfoCache is already initialized. Contract.Assert(matchingTypes.Count != 1); if (matchingTypes.Count == 0) { // no matching types throw new HttpResponseException(request.CreateResponse( HttpStatusCode.NotFound, "The API '" + controllerName + "' doesn't exist")); } // multiple matching types throw new HttpResponseException(request.CreateResponse( HttpStatusCode.InternalServerError, CreateAmbiguousControllerExceptionMessage(request.GetRouteData().Route, controllerName.Name, matchingTypes))); }
public ICollection <Type> GetControllerTypes(ControllerIdentification controllerName) { if (String.IsNullOrEmpty(controllerName.Name)) { throw new ArgumentNullException("controllerName"); } var matchingTypes = new HashSet <Type>(); ILookup <string, Type> namespaceLookup; if (this._cache.Value.TryGetValue(controllerName, out namespaceLookup)) { foreach (var namespaceGroup in namespaceLookup) { matchingTypes.UnionWith(namespaceGroup); } } return(matchingTypes); }