Exemple #1
0
        /// <summary>
        /// Initializes the node.
        /// </summary>
        /// <param name="context">The parent.</param>
        private void InitializeNode(object context)
        {
            Type contextType = (context == null || context is Type ? context as Type : context.GetType());

            if (accessor == null || accessor.RequiresRefresh(contextType))
            {
                memberName = this.getText();

                // clear cached member info if context type has changed (for example, when ASP.NET page is recompiled)
                if (accessor != null && accessor.RequiresRefresh(contextType))
                {
                    accessor = null;
                }

                // initialize this node if necessary
                if (contextType != null && accessor == null)
                {
                    // try to initialize node as ExpandoObject value
                    if (contextType == typeof(ExpandoObject))
                    {
                        Type type = TypeRegistry.ResolveType(memberName);
                        if (type != null)
                        {
                            accessor = new TypeValueAccessor(TypeResolutionUtils.ResolveType(memberName));
                        }
                        else
                        {
                            accessor = new ExpandoObjectValueAccessor(memberName);
                        }
                    }
                    // try to initialize node as enum value first
                    else if (contextType.IsEnum)
                    {
                        try
                        {
                            accessor = new EnumValueAccessor(Enum.Parse(contextType, memberName, true));
                        }
                        catch (ArgumentException)
                        {
                            // ArgumentException will be thrown if specified member name is not a valid
                            // enum value for the context type. We should just ignore it and continue processing,
                            // because the specified member could be a property of a Type class (i.e. EnumType.FullName)
                        }
                    }

                    // then try to initialize node as property or field value
                    if (accessor == null)
                    {
                        // check the context type first
                        accessor = GetPropertyOrFieldAccessor(contextType, memberName, BINDING_FLAGS);

                        // if not found, probe the Type type
                        if (accessor == null && context is Type)
                        {
                            accessor = GetPropertyOrFieldAccessor(typeof(Type), memberName, BINDING_FLAGS);
                        }
                    }
                }

                // if there is still no match, try to initialize node as type accessor
                if (accessor == null)
                {
                    try
                    {
                        if (context is IDictionary ctx && ctx.Contains(memberName))
                        {
                            accessor = new IDictionaryValueAccessor(memberName);
                        }
                        else if (evalContext != null && evalContext.Variables != null && evalContext.Variables.ContainsKey(memberName))
                        {
                            accessor = new IDictionaryValueAccessor(memberName);
                        }
                        else if ((contextType?.IsValueType).GetValueOrDefault(false))
                        {
                            accessor = new ValueTypeAccessor();
                        }
                        else
                        {
                            accessor = new TypeValueAccessor(TypeResolutionUtils.ResolveType(memberName));
                        }
                    }