MVC 프레임의 캐시

9911 단어
프로그램에 캐시를 넣는 목적은 프로그램의 성능을 향상시키고 데이터의 검색 효율을 높이기 위해서이다. MVC 프레임워크에도 Controller의 일치 검색, Controller, ControllerDescriptorCache 등 매우 많은 캐시를 도입했다.대부분의 캐시 디자인은 키-value의 구조를 사용했다.
ControllerTypeCache
ControllerTypeCache 클래스는 응용 프로그램이 집중된 Controller 형식에 대한 캐시입니다. 요청이 MVC 프레임워크에 들어가면 RouteData의 ControllerName과 이름 공간에 따라 정확한 Controller 형식을 찾아야 합니다.만약 프로그램이 비교적 크면 Controller는 프로그램의 모든 dll의 클래스를 일치하게 찾아야 하기 때문에 효율이 매우 낮을 것이다.
MVC 프레임워크에서 Controller 클래스에 대한 검색 일치에 대해 ControllerTypeCache 클래스를 도입했습니다. 캐시 클래스에는 Dictionary의 캐시 구조가 존재합니다. 이 구조에서 키는 Controller 접미사를 제거한 Controller 형식의Name이고 Value 값은 Ilookup 구조입니다. 그 중에서 키 값은 명명 공간 이름이고 Value는 Controller 유형입니다.그리고 이 키들은 모두 대소문자를 무시한다.
     
     public void EnsureInitialized(IBuildManager buildManager)
     {
         if (_cache == null)
         {
            lock (_lockObj)
            {
                if (_cache == null)
                 {
                     List<Type> controllerTypes = TypeCacheUtil.GetFilteredTypesFromAssemblies(TypeCacheName, IsControllerType, buildManager);
                     var groupedByName = controllerTypes.GroupBy(
                                          t => t.Name.Substring(0, t.Name.Length - "Controller".Length), StringComparer.OrdinalIgnoreCase);
                        _cache = groupedByName.ToDictionary(
                                               g => g.Key,
                                               g => g.ToLookup(t => t.Namespace ?? String.Empty, StringComparer.OrdinalIgnoreCase),
                                               StringComparer.OrdinalIgnoreCase);
                    }
                }
            }
        }

ControllerType Cache 클래스에서 Ensure Initialized 방법은 캐시 구조를 구축하는 것입니다.GetFilteredTypes From Assemblies 방법은 프로그램이 모든 Control 형식을 모으는 데 사용됩니다. MVC 프레임워크에서 프로그램이 시작될 때 모든 dll 클래스의 Controller 형식을 불러오고 Ibuild Manager 인터페이스를 호출하는 방법인Create Cached File 방법은 이 유형을 디스크 파일에 서열화합니다.다음 요청이 오면 디스크 파일에서 직접 불러옵니다. 파일 이름은 'MVC-ControllerTypeCache.xml' 입니다.캐치 캐시 파일의 주소는 HttpRuntime입니다.CodegenDir+"//UserCache//MVC-ControllerTypeCache.xml";
Reader Writer Cache Reader Writer Cache는 읽기와 쓰기 캐시 추상 클래스로 그의 캐시 구조도 키-value의 형식이다. MVC 프레임워크에서 Controller Descriptor Cache 클래스,Action Method Dispatcher Cache 클래스는 모두 이 추상 클래스를 계승했다.ControllerDescriptorCache 클래스에서 키는 Controller의 Type 유형이고 Value는 ControllerDescriptor 클래스입니다.ActionMethodDispatcherCache 클래스 중 키는 action 방법의 MethodInfo이고Value는ActionMethodDispatcher 클래스이다.
Reader Writer Cache 클래스에서 캐시를 읽거나 설정하는 중요한 방법이 있습니다.
 private readonly ReaderWriterLockSlim _readerWriterLock = new ReaderWriterLockSlim();
 protected TValue FetchOrCreateItem<TArgument>(TKey key, Func<TArgument, TValue> creator, TArgument state)
 {
   // first, see if the item already exists in the cache
    _readerWriterLock.EnterReadLock();
    try
    {
      TValue existingEntry;
      if (_cache.TryGetValue(key, out existingEntry))
        {
           return existingEntry;
        }
     }
     finally
     {
          _readerWriterLock.ExitReadLock();
     }

     // insert the new item into the cache
     TValue newEntry = creator(state);
     _readerWriterLock.EnterWriteLock();
     try
     {
        TValue existingEntry;
        if (_cache.TryGetValue(key, out existingEntry))
        {
           // another thread already inserted an item, so use that one
           return existingEntry;
         }
         _cache[key] = newEntry;
          return newEntry;
      }
      finally
      {
         _readerWriterLock.ExitWriteLock();
      }
    }

FetchOrcreateItem 방법에서 Reader Writer LockSlim 클래스를 도입했는데 이 클래스의 목적은 자원 접근의 잠금 상태를 관리하는 데 사용되며 다중 스레드 읽기나 독점적 쓰기 접근을 실현할 수 있다. 키에 따라 vlaue 값을 가져올 때 읽기 캐시를 읽을 때 Enter ReadLock 방법에 따라 읽기 자물쇠를 추가하고 읽기가 끝난 후에 ExitReadLock 방법을 통해 읽기 자물쇠를 풀 수 있다.캐시가 명중하지 않으면 생성 형식의 의뢰를 호출하여value를 생성하여 캐시에 기록하고 캐시에 쓰기 전에 다시 캐시에서 읽으며 없으면 쓰기를 하여 중복 쓰기를 방지합니다.
  
     protected override ControllerDescriptor GetControllerDescriptor(ControllerContext controllerContext)
     {
         // Frequently called, so ensure delegate is static
         Type controllerType = controllerContext.Controller.GetType();
         ControllerDescriptor controllerDescriptor = DescriptorCache.GetDescriptor(
                 controllerType: controllerType,
                 creator: ReflectedAsyncControllerDescriptor.DefaultDescriptorFactory,
                 state: controllerType);
            return controllerDescriptor;
      }

 ReflectedAttributeCache
Reflected Attribute Cache 클래스에서 캐시가 action 방법의 일부 특성에 작용하는 목록 캐시입니다. 이 캐시에서 방법에 대한 특성 정보를 빨리 얻을 수 있습니다. 이 캐시 클래스의 클래스 구조도 키-value 형식을 사용합니다.
     
      private static readonly ConcurrentDictionary<MethodInfo, ReadOnlyCollection<ActionMethodSelectorAttribute>> _actionMethodSelectorAttributeCache = new ConcurrentDictionary<MethodInfo, ReadOnlyCollection<ActionMethodSelectorAttribute>>();
        private static readonly ConcurrentDictionary<MethodInfo, ReadOnlyCollection<ActionNameSelectorAttribute>> _actionNameSelectorAttributeCache = new ConcurrentDictionary<MethodInfo, ReadOnlyCollection<ActionNameSelectorAttribute>>();
        private static readonly ConcurrentDictionary<MethodInfo, ReadOnlyCollection<FilterAttribute>> _methodFilterAttributeCache = new ConcurrentDictionary<MethodInfo, ReadOnlyCollection<FilterAttribute>>();

        private static readonly ConcurrentDictionary<Type, ReadOnlyCollection<FilterAttribute>> _typeFilterAttributeCache = new ConcurrentDictionary<Type, ReadOnlyCollection<FilterAttribute>>();

Reflected Attribute Cache 클래스에는 4가지 캐시가 존재하는데 캐시 형식은 모두 ConcurrentDictionary 형식입니다.
    _actionMethod Selector Attribute Cache 캐시: 키는 action 방법의 Method Info이고value는ActionMethod Selector Attribute 추상 클래스의 일부 하위 클래스(Http Post Attribute, Http Get Attribute)의 읽기 전용 집합을 계승합니다.ActionMethodSelectorAttribute 클래스의 목적은 요청을 선별하는 방식입니다.
    _actionName Selector Attribute Cache 캐시: 키는 action 방법의 Method Info이고value는ActionName Selector Attribute 추상적인 클래스의 일부 하위 클래스(ActionName Attribute)의 읽기 전용 집합을 계승합니다.ActionMethodSelectorAttribute 클래스의 목적은 요청 방법의 이름을 선별하는 것입니다.
     _methodFilterAttributeCache 캐시: 키는 action 방법의 MethodInfo이고value는 FilterAttribute 추상 클래스의 일부 하위 클래스의 읽기 전용 집합을 계승합니다.FilterAttribute 클래스의 목적은 action의 필터 특성입니다.
    _typeFilterAttributeCache 캐시: 키는 Controller 클래스의 Type이고value는 FilterAttribute 추상 클래스의 일부 하위 클래스의 읽기 전용 집합을 계승합니다.FilterAttribute 클래스의 목적은 Controller의 필터 특성입니다.
Reflected AttributeCache 클래스에서 특성 집합을 가져오는 것은GetAttributes 방법을 통해
  private static ReadOnlyCollection<TAttribute> GetAttributes<TMemberInfo, TAttribute>(ConcurrentDictionary<TMemberInfo, ReadOnlyCollection<TAttribute>> lookup, TMemberInfo memberInfo)
            where TAttribute : Attribute
            where TMemberInfo : MemberInfo
  {
        // Frequently called, so use a static delegate
        // An inline delegate cannot be used because the C# compiler does not cache inline delegates that reference generic method arguments
        return lookup.GetOrAdd( memberInfo,
                               CachedDelegates<TMemberInfo, TAttribute>.GetCustomAttributes);
   }

  private static class CachedDelegates<TMemberInfo, TAttribute>
            where TAttribute : Attribute
            where TMemberInfo : MemberInfo
  {
        internal static Func<TMemberInfo, ReadOnlyCollection<TAttribute>> GetCustomAttributes = (TMemberInfo memberInfo) =>
         {
                return new ReadOnlyCollection<TAttribute>((TAttribute[])memberInfo.GetCustomAttributes(typeof(TAttribute), inherit: true));
         };
  }

 


 

좋은 웹페이지 즐겨찾기