using System; using System.Collections.Generic; using System.Text; using System.Reflection; namespace ScriptNET.Runtime { /// /// Default object binder used by Runtime /// public class ObjectBinderExtended : ObjectBinder, IObjectBinder { IObjectBind IObjectBinder.BindToMethod(object target, string methodName, Type[] genericParameters, object[] arguments) { IScriptable scriptable = target as IScriptable; if (scriptable != null) { IObjectBind bind = scriptable.GetMethod(methodName, null); if (bind == null) bind = base.BindToMethod(scriptable.Instance, methodName, genericParameters, arguments); else return new DynamicMethodBind(scriptable, bind, arguments); if (bind != null) return bind; } return base.BindToMethod(target, methodName, genericParameters, arguments); } IObjectBind IObjectBinder.BindToIndex(object target, object[] arguments, bool setter) { IScriptable scriptable = target as IScriptable; if (scriptable != null) { IObjectBind bind = base.BindToIndex(scriptable.Instance, arguments, setter); if (bind != null) return bind; } return base.BindToIndex(target, arguments, setter); } #region DynamicMethodBind protected class DynamicMethodBind : IObjectBind { IScriptable scriptable; IObjectBind dynamicMethod; object[] arguments; public DynamicMethodBind(IScriptable scriptable, IObjectBind dynamicMethod, object[] arguments) { this.scriptable = scriptable; this.dynamicMethod = dynamicMethod; this.arguments = arguments; } #region IInvokable Members public bool CanInvoke() { return scriptable != null && dynamicMethod != null; } public object Invoke(IScriptContext context, object[] args) { context.CreateScope(); context.SetItem("me", scriptable.Instance); context.SetItem("body", scriptable); object rez = RuntimeHost.NullValue; try { rez = dynamicMethod.Invoke(context, arguments); } finally { context.RemoveLocalScope(); } if (rez != RuntimeHost.NullValue) { return rez; } else { throw new ScriptException(string.Format("Dynamic method call failed in object {0}", scriptable.ToString())); } } #endregion } #endregion } }