private static List<Type> ReadTypesFromCache(string cacheName, Predicate<Type> predicate, HttpControllerTypeCacheSerializer serializer) { try { Stream stream = BuildManager.ReadCachedFile(cacheName); if (stream != null) { using (StreamReader reader = new StreamReader(stream)) { ICollection<Type> deserializedTypes = serializer.DeserializeTypes(reader); if (deserializedTypes != null && deserializedTypes.All(type => predicate(type))) { // If all read types still match the predicate, success! return deserializedTypes.ToList(); } } } } catch { // cache failures are not considered fatal -- keep running. } return null; }
private static void SaveTypesToCache(string cacheName, IEnumerable<Type> matchingTypes, HttpControllerTypeCacheSerializer serializer) { try { Stream stream = BuildManager.CreateCachedFile(cacheName); if (stream != null) { using (StreamWriter writer = new StreamWriter(stream)) { serializer.SerializeTypes(matchingTypes, writer); } } } catch { // cache failures are not considered fatal -- keep running. } }
/// <summary> /// Returns a list of controllers available for the application. /// </summary> /// <returns>An <see cref="ICollection{Type}" /> of controllers.</returns> public override ICollection<Type> GetControllerTypes(IAssembliesResolver assembliesResolver) { HttpControllerTypeCacheSerializer serializer = new HttpControllerTypeCacheSerializer(); // First, try reading from the cache on disk List<Type> matchingTypes = ReadTypesFromCache(TypeCacheName, IsControllerTypePredicate, serializer); if (matchingTypes != null) { return matchingTypes; } // If reading from the cache failed, enumerate over every assembly looking for a matching type matchingTypes = base.GetControllerTypes(assembliesResolver).ToList(); // Finally, save the cache back to disk SaveTypesToCache(TypeCacheName, matchingTypes, serializer); return matchingTypes; }