using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection; namespace ScriptNET.Runtime { public partial class ObjectBinder { protected abstract class BaseHandler { IObjectBinder binder; public BaseHandler(IObjectBinder parent) { binder = parent; } protected bool CanBind(MemberInfo member) { return binder.CanBind(member); } } protected class PropertyHandler : BaseHandler, IGetter, ISetter, IHandler { public PropertyHandler(IObjectBinder parent):base(parent) { } #region IGetter Members public object Get(string name, object instance, Type type, params object[] arguments) { PropertyInfo pi = GetProperty(type, name); if (pi == null) return NoResult; if (!CanBind(pi)) return NoResult; return pi.GetValue(instance, arguments); } #endregion #region ISetter Members public object Set(string name, object instance, Type type, object value, params object[] arguments) { PropertyInfo pi = GetProperty(type, name); if (pi == null) return NoResult; if (!CanBind(pi)) return NoResult; if (value != null && pi.PropertyType.IsAssignableFrom(value.GetType())) { pi.SetValue(instance, value, null); } else { pi.SetValue(instance, RuntimeHost.Binder.ConvertTo(value, pi.PropertyType), arguments); } return value; } private PropertyInfo GetProperty(Type type, string name) { return type.GetProperties(ObjectBinder.PropertyFilter).Where(pi => pi.Name == name).FirstOrDefault(); } #endregion } protected class FieldHandler : BaseHandler, IGetter, ISetter, IHandler { public FieldHandler(IObjectBinder parent) : base(parent) { } #region IGetter Members public object Get(string name, object instance, Type type, params object[] arguments) { FieldInfo fi = type.GetField(name, ObjectBinder.FieldFilter); if (fi == null) return NoResult; if (!CanBind(fi)) return NoResult; return fi.GetValue(instance); } #endregion #region ISetter Members public object Set(string name, object instance, Type type, object value, params object[] arguments) { FieldInfo fi = type.GetField(name, ObjectBinder.FieldFilter); if (fi == null) return NoResult; if (!CanBind(fi)) return NoResult; fi.SetValue(instance, RuntimeHost.Binder.ConvertTo(value, fi.FieldType)); return value; } #endregion } protected class EventHandler : BaseHandler, IGetter, ISetter, IHandler { public EventHandler(IObjectBinder parent) : base(parent) { } #region IGetter Members public object Get(string name, object instance, Type type, params object[] arguments) { EventInfo ei = type.GetEvent(name, ObjectBinder.PropertyFilter); if (ei == null) return NoResult; if (!CanBind(ei)) return NoResult; //Type eventHelper = typeof(EventHelper<>); //Type actualHelper = eventHelper.MakeGenericType(ei.EventHandlerType); return ei; } #endregion #region ISetter Members public object Set(string name, object instance, Type type, object value, params object[] arguments) { EventInfo ei = type.GetEvent(name, ObjectBinder.PropertyFilter); if (ei == null) return NoResult; if (!CanBind(ei)) return NoResult; if (!(value is RemoveDelegate)) EventBroker.AssignEvent(ei, instance, (IInvokable)value); else EventBroker.RemoveEvent(ei, instance, (IInvokable)value); return value; } #endregion } protected class MethodGetter : BaseHandler, IGetter { public MethodGetter(IObjectBinder parent) : base(parent) { } #region IGetter Members public object Get(string name, object instance, Type type, params object[] arguments) { MethodInfo[] methods = type.GetMethods(ObjectBinder.MethodFilter).Where(m => m.Name == name && CanBind(m)).ToArray(); if (methods == null || methods.Length == 0) return NoResult; return new LateBoundMethod(name, instance); } #endregion } //protected class MutantHandler : IGetter, ISetter, IHandler //{ // #region IGetter Members // public object Get(string name, object instance, Type type, params object[] arguments) // { // IMutant dm = instance as IMutant; // if (dm == null) return NoResult; // return dm.Get(name, null); // } // #endregion // #region ISetter Members // public object Set(string name, object instance, Type type, object value, params object[] arguments) // { // IMutant dm = instance as IMutant; // if (dm == null) return NoResult; // dm.Set(name, value, null); // return value; // } // #endregion //} protected class ScriptableHandler : BaseHandler, IGetter, ISetter, IHandler { public ScriptableHandler(IObjectBinder parent) : base(parent) { } #region IGetter Members public object Get(string name, object instance, Type type, params object[] arguments) { IScriptable dm = instance as IScriptable; if (dm == null) return NoResult; return dm.GetMember(name, arguments).GetValue(); } #endregion #region ISetter Members public object Set(string name, object instance, Type type, object value, params object[] arguments) { IScriptable dm = instance as IScriptable; if (dm == null) return NoResult; dm.GetMember(name, arguments).SetValue(value); return value; } #endregion } protected class NestedTypeGetter : BaseHandler, IGetter { public NestedTypeGetter(IObjectBinder parent) : base(parent) { } #region IGetter Members public object Get(string name, object instance, Type type, params object[] arguments) { Type nested = type.GetNestedType(name, ObjectBinder.NestedTypeFilter); if (nested == null) return NoResult; return nested; } #endregion } //protected class NameSpaceGetter : IGetter //{ // #region IGetter Members // public object Get(string name, object instance, Type type, params object[] arguments) // { // NameSpaceMutant nameSpace = NameSpaceCache.Get(type.Namespace); // new NameSpaceMutant(type.Namespace); // object rez = nameSpace.Get(name, null); // if (rez == null) return NoResult; // return rez; // } // #endregion //} } }