public static object RuntimeBind(object model, LateBoundExpressionNode node) { var itemName = node.ItemName; var memberLocator = node.MemberLocator; CheckNotNull($"Could not bind expression with name '{node.ItemName}'. The value is null.", model, node); var runtimeModel = model as IRuntimeModel; if (runtimeModel?.Data != null) model = runtimeModel.Data; var binder = TypeHelperBinder.GetBinder(model, itemName, memberLocator); if (binder == null) throw new VeilCompilerException("Unable to late-bind '{0}' against model {1}".FormatInvariant(itemName, model.GetType().Name), node); var result = binder(model); return result; }
public static object RuntimeBind(object model, LateBoundExpressionNode node) { var itemName = node.ItemName; var memberLocator = node.MemberLocator; CheckNotNull(string.Format("Could not bind expression with name '{0}'. The value is null.", node.ItemName), model, node); var runtimeModel = model as IRuntimeModel; if (runtimeModel != null && runtimeModel.Data != null) model = runtimeModel.Data; var binder = lateBoundCache.GetOrAdd(Tuple.Create(model.GetType(), itemName), new Func<Tuple<Type, string>, Func<object, object>>(pair => { var type = pair.Item1; var name = pair.Item2; if (name.EndsWith("()")) { var function = memberLocator.FindMember(type, name.Substring(0, name.Length - 2), MemberTypes.Method) as MethodInfo; if (function != null) return DelegateBuilder.FunctionCall(type, function); } var property = memberLocator.FindMember(type, name, MemberTypes.Property) as PropertyInfo; if (property != null) return DelegateBuilder.Property(type, property); var field = memberLocator.FindMember(type, name, MemberTypes.Field) as FieldInfo; if (field != null) return DelegateBuilder.Field(type, field); var dictionaryType = type.GetDictionaryTypeWithKey<string>(); if (dictionaryType != null) return DelegateBuilder.Dictionary(dictionaryType, name); return null; })); if (binder == null) throw new VeilCompilerException("Unable to late-bind '{0}' against model {1}".FormatInvariant(itemName, model.GetType().Name), node); var result = binder(model); return result; }