/// <summary>
        /// Initializes the routine type descriptor.
        /// </summary>
        private void Initialize()
        {
            var typeInfo    = this.Type.GetTypeInfo();
            var routineType = typeInfo.GetCustomAttribute <RoutineTypeAttribute>()?.Type ?? this.Type;

            if (routineType != this.Type)
            {
                typeInfo = routineType.GetTypeInfo();
            }

            var routineAttribute = typeInfo.GetCustomAttribute <RoutineAttribute>();

            if (routineAttribute == null)
            {
                throw new OrmMissingRoutineMappingException($"The type '{routineType.Name}' does not have routine mapping information.");
            }

            this.TypeName    = this.Type.Name;
            this.CatalogName = routineAttribute.Catalog;
            this.SchemaName  = routineAttribute.Schema;
            this.RoutineName = routineAttribute.Name ?? routineType.Name;

            var properties = this.GetProperties(this.Type, routineType);

            this.Parameters = ParameterPropertyDescriptor.Create(properties);
        }
        /// <summary>
        /// Creates a new instance of <see cref="ParameterPropertyDescriptor"/> from a <see cref="PropertyDecoration"/> instance.
        /// </summary>
        /// <remarks>
        /// If the property is not decorated with the <see cref="ParameterAttribute"/> the method will return <c>null</c>.
        /// </remarks>
        /// <param name="property">The property info to use.</param>
        /// <returns>A Parameter property descriptor or null otherwise.</returns>
        internal static IParameterPropertyDescriptor Create(PropertyDecoration property)
        {
            if (property == null)
            {
                throw new ArgumentNullException(nameof(property), "The property collection can not be null.");
            }

            var descriptor = new ParameterPropertyDescriptor(property);

            return(descriptor.Initialize() ? descriptor : null);
        }