PBMining

Searching...
Monday, July 30, 2012

Exploring MVC framework in deep - TypeCacheUtil Class

10:14 AM

In My Previous post i explain about BuildManagerWrapper. TypeCacheUtil class used BuildManagerWrapper for extracting controller Types from reference assembly and Reading or Writing Controller Type Cache file. some other operation is performed by TypeCacheUtil class like apply some criteria like Type should be Class, Public,Not Abstract. for checking some other criteria ControllerTypeCache class pass Delegate function its check that Controller class name should be end with "Controller" and its assignable to IController interface. lets see how its working.

    internal static class TypeCacheUtil {

     }         

TypeCacheUtil is an internal class.Inside it all things are static so it can be used directly without creating instance there is one method GetFilteredTypesFromAssemblies this method is public.ControllerTypeCache class call this method for retrieving all controllers from referenced assemblies.

         public static List<Type> GetFilteredTypesFromAssemblies(string cacheName, Predicate<Type> predicate, IBuildManager buildManager) {
              TypeCacheSerializer serializer = new TypeCacheSerializer();

              // first, try reading from the cache on disk
              List<Type> matchingTypes = ReadTypesFromCache(cacheName, predicate, buildManager, serializer);
              if (matchingTypes != null) {
                  return matchingTypes;
              }

              // if reading from the cache failed, enumerate over every assembly looking for a matching type
              matchingTypes = FilterTypesInAssemblies(buildManager, predicate).ToList();

              // finally, save the cache back to disk
              SaveTypesToCache(cacheName, matchingTypes, buildManager, serializer);

              return matchingTypes;
          }
    

There are some other private method inside this class. FilterTypesInAssemblies method use BuildManager instance that is passed By DefaultControllerFactory to get All referenced assemblies and Extract All the class types an assembly contain and select the class type that meet the criteria of valid controller type.


      private static IEnumerable<Type> FilterTypesInAssemblies(IBuildManager buildManager, Predicate<Type> predicate) {
              // Go through all assemblies referenced by the application and search for types matching a predicate
              IEnumerable<Type> typesSoFar = Type.EmptyTypes;

              ICollection assemblies = buildManager.GetReferencedAssemblies();
              foreach (Assembly assembly in assemblies) {
                  Type[] typesInAsm;
                  try {
                      typesInAsm = assembly.GetTypes();
                  }
                  catch (ReflectionTypeLoadException ex) {
                      typesInAsm = ex.Types;
                  }
                  typesSoFar = typesSoFar.Concat(typesInAsm);
              }
              return typesSoFar.Where(type => TypeIsPublicClass(type) && predicate(type));
          }

     private static bool TypeIsPublicClass(Type type) {
              return (type != null && type.IsPublic && type.IsClass && !type.IsAbstract);
          }

GetFilteredTypesFromAssemblies class save that types in disk cache.it use one class TypeCacheSerializer. This class is responsible for creating xml file structure from types and store it in disk.

There are two more methods in this class SaveTypesToCache and ReadTypesFromCache.These methods are used to serialize or deserialize controller types using TypeCacheSerializer class.


    [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Cache failures are not fatal, and the code should continue executing normally.")]
             internal static List<Type> ReadTypesFromCache(string cacheName, Predicate<Type> predicate, IBuildManager buildManager, TypeCacheSerializer serializer) {
                 try {
                     Stream stream = buildManager.ReadCachedFile(cacheName);
                     if (stream != null) {
                         using (StreamReader reader = new StreamReader(stream)) {
                             List<Type> deserializedTypes = serializer.DeserializeTypes(reader);
                             if (deserializedTypes != null && deserializedTypes.All(type => TypeIsPublicClass(type) && predicate(type))) {
                                 // If all read types still match the predicate, success!
                                 return deserializedTypes;
                             }
                         }
                     }
                 }
                 catch {
                 }

                 return null;
             }

             [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Cache failures are not fatal, and the code should continue executing normally.")]
             internal static void SaveTypesToCache(string cacheName, IList<Type> matchingTypes, IBuildManager buildManager, TypeCacheSerializer serializer) {
                 try {
                     Stream stream = buildManager.CreateCachedFile(cacheName);
                     if (stream != null) {
                         using (StreamWriter writer = new StreamWriter(stream)) {
                             serializer.SerializeTypes(matchingTypes, writer);
                         }
                     }
                 }
                 catch {
                 }
             }


    

Definition of this methods are simple its use BuildManager instance to create or read cache file and use instance of TypeCacheSerializer to create or read a XML format from or to cache.

0 comments:

Post a Comment

Write your review about this post.