/// <summary> /// Creates the <see cref="IHttpController"/> specified by <paramref name="controllerType"/> using the given <paramref name="request"/> /// </summary> /// <param name="request">The request message.</param> /// <param name="controllerType">Type of the controller.</param> /// <param name="controllerDescriptor">The controller descriptor</param> /// <returns>An instance of type <paramref name="controllerType"/>.</returns> public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) { if (request == null) { throw Error.ArgumentNull("request"); } if (controllerDescriptor == null) { throw Error.ArgumentNull("controllerDescriptor"); } if (controllerType == null) { throw Error.ArgumentNull("controllerType"); } try { // First check in the local fast cache and if not a match then look in the broader // HttpControllerDescriptor.Properties cache if (_fastCache == null) { // If dependency resolver returns controller object then keep asking it whenever we need a new instance IHttpController instance = (IHttpController)request.GetDependencyScope().GetService(controllerType); if (instance != null) { return(instance); } // Otherwise create a delegate for creating a new instance of the type Func <IHttpController> activator = TypeActivator.Create <IHttpController>(controllerType); Tuple <HttpControllerDescriptor, Func <IHttpController> > cacheItem = Tuple.Create(controllerDescriptor, activator); Interlocked.CompareExchange(ref _fastCache, cacheItem, null); // Execute the delegate return(activator()); } else if (_fastCache.Item1 == controllerDescriptor) { // If the key matches and we already have the delegate for creating an instance then just execute it return(_fastCache.Item2()); } else { // If the key doesn't match then lookup/create delegate in the HttpControllerDescriptor.Properties for // that HttpControllerDescriptor instance Func <IHttpController> activator = (Func <IHttpController>)controllerDescriptor.Properties.GetOrAdd( _cacheKey, key => TypeActivator.Create <IHttpController>(controllerType)); return(activator()); } } catch (Exception ex) { throw Error.InvalidOperation(ex, SRResources.DefaultControllerFactory_ErrorCreatingController, controllerType.Name); } }
// Returns the controller instance from the dependency resolver if there is one registered // else returns the activator that calls the default ctor for the give controllerType. private static IHttpController GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, out Func <IHttpController> activator) { Contract.Assert(request != null); Contract.Assert(controllerType != null); // If dependency resolver returns controller object then use it. IHttpController instance = (IHttpController)request.GetDependencyScope().GetService(controllerType); if (instance != null) { activator = null; return(instance); } // Otherwise create a delegate for creating a new instance of the type activator = TypeActivator.Create <IHttpController>(controllerType); return(null); }