/// <inheritdoc />
        /// <exception cref="ArgumentException">Thrown when <paramref name="propertyTemplate" /> is null, empty string or whitespace</exception>
        /// <exception cref="InvalidTemplateException"></exception>
        /// <exception cref="MemberNotFoundException"></exception>
        /// <exception cref="InvalidOperationException"></exception>
        public virtual object GetValue(string propertyTemplate)
        {
            if (string.IsNullOrWhiteSpace(propertyTemplate))
            {
                throw new ArgumentException(ArgumentHelper.EmptyStringParamMessage, nameof(propertyTemplate));
            }

            propertyTemplate = propertyTemplate.Trim();
            MemberTemplateParts templateParts = ParseTemplate(propertyTemplate);

            if (string.IsNullOrWhiteSpace(templateParts.MemberName))
            {
                throw new InvalidTemplateException(string.Format(Constants.InvalidTemplateMessage, propertyTemplate));
            }

            Type type = TypeProvider.GetType(templateParts.TypeName);

            string[]   props            = templateParts.MemberName.Split(PropertiesSeparator);
            MemberInfo member           = GetFirstMember(props[0], type);
            object     firstMemberValue = GetFirstMemberValue(member, type);

            if (props.Length == 1)
            {
                return(firstMemberValue ?? _reflectionHelper.GetNullValueAttributeValue(member));
            }
            return(_reflectionHelper.GetValueOfPropertiesChain(string.Join(PropertiesSeparator.ToString(), props.Skip(1)), firstMemberValue));
        }