Esempio n. 1
0
        /// <summary>
        /// Parses a term key string and returns a term describing it. All terms are created here.
        /// The main caller is TypeCache.MakeTerm, but it's also called from places that use a
        /// dynamic domain (processors).
        /// </summary>
        public Term Parse(Type resource, string key, string componentSeparator, TermBindingRule bindingRule, ICollection <string> dynDomain)
        {
            var term = new Term(componentSeparator);

            Property propertyMaker(string str)
            {
                if (string.IsNullOrWhiteSpace(str))
                {
                    throw new InvalidSyntax(ErrorCodes.InvalidConditionSyntax, $"Invalid condition '{str}'");
                }
                if (dynDomain?.Contains(str, StringComparer.OrdinalIgnoreCase) == true)
                {
                    return(DynamicProperty.Parse(str));
                }

                Property make(Type type)
                {
                    switch (bindingRule)
                    {
                    case TermBindingRule.DeclaredWithDynamicFallback:
                        try
                        {
                            return(TypeCache.FindDeclaredProperty(type, str));
                        }
                        catch (UnknownProperty)
                        {
                            return(DynamicProperty.Parse(str));
                        }

                    case TermBindingRule.DynamicWithDeclaredFallback: return(DynamicProperty.Parse(str, true));

                    case TermBindingRule.OnlyDeclared:
                        try
                        {
                            return(TypeCache.FindDeclaredProperty(type, str));
                        }
                        catch (UnknownProperty)
                        {
                            if (type.GetSubclasses().Any(subClass => TypeCache.TryFindDeclaredProperty(subClass, str, out _)))
                            {
                                return(DynamicProperty.Parse(str));
                            }
                            throw;
                        }

                    default: throw new Exception();
                    }
                }

                return(term.LastOrDefault() switch
                {
                    null => make(resource),
                    DeclaredProperty declared => make(declared.Type),
                    _ => DynamicProperty.Parse(str)
                });
            }
Esempio n. 2
0
        /// <summary>
        /// Creates a new term for the given type, with the given key, component separator and binding rule. If a term with
        /// the given key already existed, simply returns that one.
        /// </summary>
        public Term MakeOrGetCachedTerm(Type resource, string key, string componentSeparator, TermBindingRule bindingRule)
        {
            var tuple = (resource.GetRESTableTypeName(), key.ToLower(), bindingRule);

            if (!TermCache.TryGetValue(tuple, out var term))
            {
                term = TermCache[tuple] = Parse(resource, key, componentSeparator, bindingRule, null);
            }
            return(term);
        }