private static void LinksPropertyDiscovered(IResourceTypeBuilder resourceTypeConfiguration, PropertyInfo linksProperty)
        {
            Contract.Requires(resourceTypeConfiguration != null);
            Contract.Requires(linksProperty != null);

            var clrPropertyName = linksProperty.Name;

            resourceTypeConfiguration.Links(clrPropertyName);
        }
        private static void MetaPropertyDiscovered(IResourceTypeBuilder resourceTypeConfiguration, PropertyInfo metaProperty)
        {
            Contract.Requires(resourceTypeConfiguration != null);
            Contract.Requires(metaProperty != null);

            var clrPropertyName = metaProperty.Name;

            resourceTypeConfiguration.Meta(clrPropertyName);
        }
        // PUBLIC METHODS ///////////////////////////////////////////////////
        #region IResourceTypeConvention Implementation
        public IResourceTypeBuilder Apply(IResourceTypeBuilder resourceTypeConfiguration)
        {
            Contract.Requires(resourceTypeConfiguration != null);

            // Can leverage the default behavior of the HypermediaInfoConfiguration
            // constructor to use the CLR type name for the current hypermedia metadata configuration.
            resourceTypeConfiguration.Hypermedia();
            return(resourceTypeConfiguration);
        }
        private static void RelationshipsPropertyDiscovered(IResourceTypeBuilder resourceTypeConfiguration, PropertyInfo relationshipsProperty)
        {
            Contract.Requires(resourceTypeConfiguration != null);
            Contract.Requires(relationshipsProperty != null);

            var clrPropertyName = relationshipsProperty.Name;

            resourceTypeConfiguration.Relationships(clrPropertyName);
        }
        public static IMetaInfoBuilder Meta <TResource>(this IResourceTypeBuilder <TResource> resourceTypeBuilder, Expression <Func <TResource, Meta> > clrPropertySelector)
            where TResource : class
        {
            Contract.Requires(resourceTypeBuilder != null);

            var clrPropertyName = StaticReflection.GetMemberName(clrPropertySelector);

            return(resourceTypeBuilder.Meta(clrPropertyName));
        }
        public static ILinksInfoBuilder Links <TResource>(this IResourceTypeBuilder <TResource> resourceTypeBuilder, Expression <Func <TResource, Links> > clrPropertySelector)
            where TResource : class, IResource
        {
            Contract.Requires(resourceTypeBuilder != null);

            var clrPropertyName = StaticReflection.GetMemberName(clrPropertySelector);

            return(resourceTypeBuilder.Links(clrPropertyName));
        }
        private static void AttributePropertyDiscovered(IResourceTypeBuilder resourceTypeConfiguration, PropertyInfo attributeProperty)
        {
            Contract.Requires(resourceTypeConfiguration != null);
            Contract.Requires(attributeProperty != null);

            var clrPropertyName = attributeProperty.Name;
            var clrPropertyType = attributeProperty.PropertyType;

            resourceTypeConfiguration.Attribute(clrPropertyName, clrPropertyType);
        }
        private static void ResourceIdentityPropertyDiscovered(IResourceTypeBuilder resourceTypeConfiguration, PropertyInfo resourceIdentityProperty)
        {
            Contract.Requires(resourceTypeConfiguration != null);
            Contract.Requires(resourceIdentityProperty != null);

            var clrPropertyName = resourceIdentityProperty.Name;
            var clrPropertyType = resourceIdentityProperty.PropertyType;

            resourceTypeConfiguration.ResourceIdentity(clrPropertyName, clrPropertyType);
        }
        // PUBLIC METHODS ///////////////////////////////////////////////////
        #region IResourceTypeConvention Implementation
        public IResourceTypeBuilder Apply(IResourceTypeBuilder resourceTypeConfiguration)
        {
            Contract.Requires(resourceTypeConfiguration != null);

            // Use reflection, get all the directly declard, public, and instance-based type of properties for the given resource type.
            var clrResourceType = resourceTypeConfiguration.ClrType;
            var clrProperties   = clrResourceType
                                  .GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance)
                                  .ToList();

            var resourceIdentityProperty = DiscoverResourceIdentityProperty(clrResourceType, clrProperties);

            if (resourceIdentityProperty != null)
            {
                clrProperties.Remove(resourceIdentityProperty);
                ResourceIdentityPropertyDiscovered(resourceTypeConfiguration, resourceIdentityProperty);
            }

            var relationshipsProperty = DiscoverRelationshipsProperty(clrProperties);

            if (relationshipsProperty != null)
            {
                clrProperties.Remove(relationshipsProperty);
                RelationshipsPropertyDiscovered(resourceTypeConfiguration, relationshipsProperty);
            }

            var linksProperty = DiscoverLinksProperty(clrProperties);

            if (linksProperty != null)
            {
                clrProperties.Remove(linksProperty);
                LinksPropertyDiscovered(resourceTypeConfiguration, linksProperty);
            }

            var metaProperty = DiscoverMetaProperty(clrProperties);

            if (metaProperty != null)
            {
                clrProperties.Remove(metaProperty);
                MetaPropertyDiscovered(resourceTypeConfiguration, metaProperty);
            }

            // Remaining properties are attributes.
            var attributeProperties = DiscoverAttributeProperties(clrProperties);

            foreach (var attributeProperty in attributeProperties)
            {
                AttributePropertyDiscovered(resourceTypeConfiguration, attributeProperty);
            }

            return(resourceTypeConfiguration);
        }
        public static IPropertyInfo CreatePropertyInfo <TResource, TProperty>(this IResourceTypeBuilder <TResource> resourceTypeBuilder, Expression <Func <TResource, TProperty> > clrPropertySelector)
            where TResource : class
        {
            Contract.Requires(resourceTypeBuilder != null);
            Contract.Requires(clrPropertySelector != null);

            var clrDeclaringType = typeof(TResource);
            var clrPropertyType  = typeof(TProperty);
            var clrPropertyName  = StaticReflection.GetMemberName(clrPropertySelector);

            var propertyInfo = new PropertyInfo(clrDeclaringType, clrPropertyName, clrPropertyType);

            return(propertyInfo);
        }
        // PUBLIC METHODS ///////////////////////////////////////////////////
        #region Extension Methods
        public static IResourceIdentityInfoBuilder ResourceIdentity <TResource, TProperty>(this IResourceTypeBuilder <TResource> resourceTypeBuilder, Expression <Func <TResource, TProperty> > clrPropertySelector)
            where TResource : class
        {
            Contract.Requires(resourceTypeBuilder != null);
            Contract.Requires(clrPropertySelector != null);

            var clrPropertyType = typeof(TProperty);
            var clrPropertyName = StaticReflection.GetMemberName(clrPropertySelector);

            return(resourceTypeBuilder.ResourceIdentity(clrPropertyName, clrPropertyType));
        }