示例#1
0
        /// <summary>
        /// Create a new type support
        /// </summary>
        /// <param name="type">The type to analyze</param>
        /// <param name="options">The type support inspection options</param>
        public ExtendedType(Type type, TypeSupportOptions options)
        {
            Type                 = type ?? throw new ArgumentNullException();
            Attributes           = new List <Type>();
            Interfaces           = new List <Type>();
            GenericArgumentTypes = new List <Type>();
            KnownConcreteTypes   = new List <Type>();
            EnumValues           = new List <KeyValuePair <object, string> >();
            Properties           = new List <ExtendedProperty>();
            Fields               = new List <ExtendedField>();
            Constructors         = new List <ConstructorInfo>();
            EmptyConstructors    = new List <ConstructorInfo>();

            var isCachingSupported = options.BitwiseHasFlag(TypeSupportOptions.Caching);

            // if the type is cached, use it
            if (isCachingSupported && ExtendedTypeCache.Contains(type, options))
            {
                InitializeFromCache(ExtendedTypeCache.Get(type, options));
            }
            else
            {
                // inspect the type with the given options
                var typeInspector = new TypeInspector(this, options);
                typeInspector.Inspect();
                if (isCachingSupported)
                {
                    ExtendedTypeCache.CacheType(this, options);
                }
            }
        }
 /// <summary>
 /// Returns true if the extended type is cached
 /// </summary>
 /// <param name="type">The type to lookup</param>
 /// <param name="options">The options for the extended type</param>
 /// <returns></returns>
 public static bool Contains(Type type, TypeSupportOptions options)
 {
     _cacheLock.Wait();
     try
     {
         return(ContainsInternal(type, options));
     }
     finally
     {
         _cacheLock.Release();
     }
 }
 /// <summary>
 /// Get an extended type from the cache
 /// </summary>
 /// <param name="type">The type to lookup</param>
 /// <param name="options">The options for the extended type</param>
 /// <returns></returns>
 public static ExtendedType Get(Type type, TypeSupportOptions options)
 {
     _cacheLock.Wait();
     try
     {
         if (!ContainsInternal(type, options))
         {
             throw new InvalidOperationException($"Requested type '{type.Name}' is not cached");
         }
         var key = GenerateKey(type, options);
         return(Instance.CachedTypes[key]);
     }
     finally
     {
         _cacheLock.Release();
     }
 }
        /// <summary>
        /// Generates the type of key to use for the type cache
        /// </summary>
        /// <param name="type">The type to lookup</param>
        /// <param name="options">The options for the extended type</param>
        /// <returns></returns>
        private static CacheKey GenerateKey(Type type, TypeSupportOptions options)
        {
            if (options != TypeSupportOptions.All)
            {
                // does it exist with all options available?
                var allKey         = new CacheKey(type, TypeSupportOptions.All);
                var containsAllKey = Instance.CachedTypes.ContainsKey(allKey);
                if (containsAllKey)
                {
                    return(allKey);
                }
            }
            // use the key as-is
            var key = new CacheKey(type, options);

            return(key);
        }
示例#5
0
        private void InspectGenericType(ExtendedType extendedType, Type type, TypeSupportOptions options)
        {
            var genericTypeDefinition = type.GetGenericTypeDefinition();
            var args = type.GetGenericArguments();

            if (args?.Any() == true)
            {
                foreach (var arg in args)
                {
                    extendedType.GenericArgumentTypes.Add(arg);
                }
            }

            if (options.BitwiseHasFlag(TypeSupportOptions.Collections))
            {
                if (typeof(ICollection).IsAssignableFrom(genericTypeDefinition) ||
                    typeof(IList) == type ||
                    typeof(IList).IsAssignableFrom(genericTypeDefinition) ||
                    typeof(IList <>).IsAssignableFrom(genericTypeDefinition) ||
                    typeof(ICollection <>).IsAssignableFrom(genericTypeDefinition) ||
                    typeof(Collection <>).IsAssignableFrom(genericTypeDefinition)
                    )
                {
                    extendedType.IsCollection = true;
                    extendedType.ElementType  = args.FirstOrDefault();
                    if (extendedType.ElementType != null)
                    {
                        extendedType.ElementNullableBaseType = GetNullableBaseType(extendedType.ElementType);
                    }
                }

                if (genericTypeDefinition == typeof(Dictionary <,>) ||
                    genericTypeDefinition == typeof(ConcurrentDictionary <,>) ||
                    genericTypeDefinition == typeof(IDictionary <,>))
                {
                    extendedType.IsDictionary = true;
                }
            }
            if (genericTypeDefinition == typeof(KeyValuePair <,>))
            {
                extendedType.IsKeyValuePair = true;
                extendedType.ElementType    = args.FirstOrDefault();
            }
        }
 /// <summary>
 /// Cache an extended type
 /// </summary>
 /// <param name="type">The extended type to cache</param>
 /// <param name="options">The options for the extended type</param>
 public static void CacheType(ExtendedType type, TypeSupportOptions options)
 {
     _cacheLock.Wait();
     try
     {
         var key = GenerateKey(type.Type, options);
         if (!Instance.CachedTypes.ContainsKey(key))
         {
             Instance.CachedTypes.Add(key, type);
             if (key.Options == TypeSupportOptions.All)
             {
                 // remove any types with options less than all
                 RemoveLowerOptions(type.Type);
             }
         }
     }
     finally
     {
         _cacheLock.Release();
     }
 }
 /// <summary>
 /// Get the extended type for a Type
 /// </summary>
 /// <param name="type"></param>
 /// <param name="options">The type support inspection options</param>
 /// <returns></returns>
 public static ExtendedType GetExtendedType(this object type, TypeSupportOptions options)
 {
     return(new ExtendedType(type.GetType(), options));
 }
 /// <summary>
 /// Get the extended type for a Type
 /// </summary>
 /// <param name="type"></param>
 /// <param name="options">The type support inspection options</param>
 /// <returns></returns>
 public static ExtendedType GetExtendedType(this Type type, TypeSupportOptions options)
 {
     return(new ExtendedType(type, options));
 }
 public CacheKey(Type type, TypeSupportOptions options)
 {
     Type    = type;
     Options = options;
 }
示例#10
0
 /// <summary>
 /// Create a new type support
 /// </summary>
 /// <param name="assemblyQualifiedFullName">The full name of the type to create, <see cref="Type.AssemblyQualifiedName"/></param>
 /// <param name="options">The type support inspection options</param>
 public ExtendedType(string assemblyQualifiedFullName, TypeSupportOptions options) : this(Type.GetType(assemblyQualifiedFullName), options)
 {
 }
示例#11
0
 /// <summary>
 /// Inspects a type
 /// </summary>
 /// <param name="extendedType">The extended type to inspect</param>
 /// <param name="options">The options to use for inspection</param>
 internal TypeInspector(ExtendedType extendedType, TypeSupportOptions options)
 {
     _extendedType = extendedType;
     _options      = options;
 }