public virtual object GetContextVariable(string variableName) { object returnValue; variableName = variableName.Trim('@'); var member = this.GetType().GetMember(variableName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase); if (member.Length > 0) { if (member[0].MemberType == MemberTypes.Property) { returnValue = ((PropertyInfo)member[0]).GetValue(this); } else if (member[0].MemberType == MemberTypes.Field) { returnValue = ((FieldInfo)member[0]).GetValue(this); } else { throw new HandlebarsRuntimeException("Context variable references a member that is not a field or property"); } } else if (_parent != null) { returnValue = _parent.GetContextVariable(variableName); } else { returnValue = null; } return(returnValue); }
//TODO: make path resolution logic smarter private object ResolvePath(BindingContext context, string path) { if (_resolutionCache.ContainsKey(context) && _resolutionCache[context].ContainsKey(path)) { return(_resolutionCache[context][path]); } var instance = context.Value; foreach (var segment in path.Split('/')) { if (segment == "..") { context = context.ParentContext; if (context == null) { throw new HandlebarsCompilerException("Path expression tried to reference parent of root"); } } else if (segment == "this") { continue; } else if (segment.StartsWith("@")) { var contextValue = context.GetContextVariable(segment.Substring(1)); if (contextValue == null) { throw new HandlebarsRuntimeException("Couldn't bind to context variable"); } instance = contextValue; break; } else { foreach (var memberName in segment.Split('.')) { try { instance = AccessMember(instance, memberName); } catch (Exception) { instance = new UndefinedBindingResult(); break; } } } } if (_resolutionCache.ContainsKey(context) == false) { _resolutionCache.Add(context, new Dictionary <string, object>()); } _resolutionCache[context].Add(path, instance); return(instance); }
//TODO: make path resolution logic smarter private object ResolvePath(BindingContext context, string path) { if (_resolutionCache.ContainsKey(context) && _resolutionCache[context].ContainsKey(path)) { return _resolutionCache[context][path]; } var instance = context.Value; foreach(var segment in path.Split ('/')) { if(segment == "..") { context = context.ParentContext; if(context == null) { throw new HandlebarsCompilerException("Path expression tried to reference parent of root"); } } else if(segment == "this") { continue; } else if (segment.StartsWith("@")) { var contextValue = context.GetContextVariable(segment.Substring(1)); if (contextValue == null) { throw new HandlebarsRuntimeException("Couldn't bind to context variable"); } instance = contextValue; break; } else { foreach (var memberName in segment.Split('.')) { try { instance = AccessMember(instance, memberName); } catch (Exception) { instance = new UndefinedBindingResult(); break; } } } } if (_resolutionCache.ContainsKey(context) == false) { _resolutionCache.Add(context, new Dictionary<string, object>()); } _resolutionCache[context].Add(path, instance); return instance; }