private IObjectSpecBuilder LoadSpecificationAndCache(Type type)
        {
            Type actualType = classStrategy.GetType(type);

            if (actualType == null)
            {
                throw new ReflectionException("Attempting to introspect a non-introspectable type " + type.FullName + " ");
            }

            IObjectSpecBuilder specification = CreateSpecification(actualType);

            if (specification == null)
            {
                throw new ReflectionException("unrecognised type " + actualType.FullName);
            }

            // We need the specification available in cache even though not yet fully introspected
            metamodel.Add(actualType, specification);

            specification.Introspect(facetDecoratorSet, new Introspector(this, metamodel));

            //if (actualType.IsGenericType && actualType.IsConstructedGenericType) {
            //    // introspect any generic type parameters
            //    actualType.GetGenericArguments().ForEach(t => LoadSpecificationAndCache(t));
            //}

            return(specification);
        }
        private int?GetValueTypeTypicalLength(Type type, IClassStrategy classStrategy)
        {
            var actualType = classStrategy.GetType(type);

            if (actualType != null)
            {
                var fn = actualType.FullName;


                if (actualType.IsArray)
                {
                    var elementType = actualType.GetElementType();

                    if (elementType == typeof(string))
                    {
                        return(null);
                    }

                    // byte[] has special facet factory

                    if (elementType != null && elementType.IsValueType && elementType == typeof(byte))
                    {
                        return(20);
                    }

                    return(null);
                }

                if (actualType.IsEnum)
                {
                    return(11);
                }

                if (TypeMap.ContainsKey(actualType))
                {
                    return(TypeMap[actualType]);
                }
            }

            return(null);
        }
        private ITypeSpecBuilder LoadSpecificationAndCache(Type type)
        {
            Type actualType = classStrategy.GetType(type);

            if (actualType == null)
            {
                throw new ReflectionException(Log.LogAndReturn($"Attempting to introspect a non-introspectable type {type.FullName} "));
            }

            ITypeSpecBuilder specification = CreateSpecification(actualType);

            if (specification == null)
            {
                throw new ReflectionException(Log.LogAndReturn($"unrecognised type {actualType.FullName}"));
            }

            // We need the specification available in cache even though not yet fully introspected
            metamodel.Add(actualType, specification);

            specification.Introspect(facetDecoratorSet, new Introspector(this));

            return(specification);
        }