Exemplo n.º 1
0
        public ExpressType(Type type)
        {
            Type = type;
            var entNameAttr = Type.GetCustomAttributes(typeof(ExpressTypeAttribute), false).FirstOrDefault();

#if DEBUG
            if (entNameAttr == null)
            {
                throw new Exception("Express Type is not defined for " + Type.Name);
            }
#endif
            _typeId           = (short)((ExpressTypeAttribute)entNameAttr).EntityTypeId;
            _expressName      = ((ExpressTypeAttribute)entNameAttr).Name;
            _expressNameUpper = _expressName.ToUpperInvariant();

            //it is not an indexed class by default. If it has any indexed properties it is an indexed class but that is detected later on.
            IndexedClass = false;

            var dta = type.GetCustomAttributes(typeof(DefinedTypeAttribute), false).FirstOrDefault() as DefinedTypeAttribute;
            if (dta != null)
            {
                _underlyingType = dta.UnderlyingType;
                if (UnderlyingType.IsGenericType && typeof(IEnumerable).IsAssignableFrom(UnderlyingType))
                {
                    var cplType = UnderlyingType.GetGenericArguments()[0];
                    if (cplType != null)
                    {
                        _underlyingComplexType = cplType;
                    }
                }
            }

            var properties =
                type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
            foreach (var propInfo in properties)
            {
                var attribute =
                    ((EntityAttributeAttribute[])propInfo.GetCustomAttributes(typeof(EntityAttributeAttribute), false)).FirstOrDefault();
                if (attribute == null)
                {
                    continue;
                }

                var metaProperty = new ExpressMetaProperty {
                    PropertyInfo = propInfo, EntityAttribute = attribute
                };
                if (attribute.Order > 0)
                {
                    _properties.Add(attribute.Order, metaProperty);
                }
                else if (attribute.State == EntityAttributeState.Derived)
                {
                    _derives.Add(metaProperty);
                }
                else
                {
                    var invAttr = propInfo.GetCustomAttributes(typeof(InverseProperty), false)[0] as InverseProperty;
                    metaProperty.InverseAttributeProperty = invAttr;
                    _inverses.Add(metaProperty);
                }

                //set up enumerable type
                if (propInfo.PropertyType.IsGenericType && typeof(IEnumerable).IsAssignableFrom(propInfo.PropertyType))
                {
                    var eType = propInfo.PropertyType;
                    while (typeof(IEnumerable).IsAssignableFrom(eType))
                    {
                        var genArgs = eType.GetGenericArguments();
                        if (genArgs.Any())
                        {
                            eType = genArgs[0];
                        }
                        else
                        {
                            break;
                        }
                    }
                    metaProperty.EnumerableType = eType;
                }

                var isIndexed =
                    propInfo.GetCustomAttributes(typeof(IndexedProperty), false).Any();
                metaProperty.IsIndexed = isIndexed;
                if (!isIndexed)
                {
                    continue;
                }

                //TODO: MC: Review with Steve. This is not true for IfcRelDefinesByProperties.RelatingPropertyDefinition in IFC4
                //Debug.Assert(typeof(IPersistEntity).IsAssignableFrom(propInfo.PropertyType)
                //    || typeof(IEnumerable<IPersistEntity>).IsAssignableFrom(propInfo.PropertyType)); //only handles to IPersistEntitiess or collecctions of IPersistEntities are indexable

                if (_indexedProperties == null)
                {
                    _indexedProperties = new List <PropertyInfo>();
                }
                if (_indexedValues == null)
                {
                    _indexedValues = new List <int>();
                }
                _indexedProperties.Add(propInfo);
                _indexedValues.Add(attribute.Order);
                IndexedClass = true; //if it has keys it must be an indexed class
            }

            //cache enumerable properties
            foreach (var prop in _properties.Values.Where(prop => typeof(IExpressEnumerable).IsAssignableFrom(prop.PropertyInfo.PropertyType)))
            {
                _expressEnumerableProperties.Add(prop);
            }
        }