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;
}