public override bool TryGetMember(GetMemberBinder binder, out object result) { if (binder == null) { throw new ArgumentNullException("binder"); } var dynamicObject = Model as RazorDynamicObject; if (dynamicObject != null) { return(dynamicObject.TryGetMember(binder, out result)); } Type modelType = Model.GetType(); var prop = modelType.GetProperty(binder.Name); if (prop == null) { if (!AllowMissingPropertiesOnDynamic) { result = null; return(false); } result = new RazorDynamicObject() { AllowMissingPropertiesOnDynamic = AllowMissingPropertiesOnDynamic, Model = new object() }; return(true); } object value = prop.GetValue(Model, null); if (value == null) { result = value; return(true); } Type valueType = value.GetType(); result = (CompilerServicesUtility.IsAnonymousType(valueType)) ? new RazorDynamicObject { Model = value } : value; return(true); }
/// <summary> /// Create a wrapper around an dynamic object. /// This wrapper ensures that we can cross the <see cref="AppDomain"/>, /// call internal methods (to make Anonymous types work), /// or call missing methods (when allowMissingMembers is true). /// </summary> /// <param name="wrapped">The object to wrap.</param> /// <param name="allowMissingMembers">true when we should not throw when missing members are invoked.</param> /// <returns>the wrapped object.</returns> public static object Create(object wrapped, bool allowMissingMembers = false) { if (IsWrapped(wrapped)) { return(wrapped); } var wrapper = new RazorDynamicObject(wrapped, allowMissingMembers); var interfaces = wrapped.GetType().GetInterfaces() .Where(t => t.IsPublic && t != typeof(IDynamicMetaObjectProvider)) .Select(MapInterface).ToArray(); if (interfaces.Length > 0) { return(Impromptu.DynamicActLike(wrapper, interfaces)); } return(wrapper); }
/// <summary> /// Create a wrapper around an dynamic object. /// This wrapper ensures that we can cross the <see cref="AppDomain"/>, /// call internal methods (to make Anonymous types work), /// or call missing methods (when allowMissingMembers is true). /// </summary> /// <param name="wrapped">The object to wrap.</param> /// <param name="allowMissingMembers">true when we should not throw when missing members are invoked.</param> /// <returns>the wrapped object.</returns> public static object Create(object wrapped, bool allowMissingMembers = false) { if (IsWrapped(wrapped)) { return(wrapped); } var wrapper = new RazorDynamicObject(wrapped, allowMissingMembers); var interfaces = wrapped.GetType().GetInterfaces() // remove IDynamicMetaObjectProvider and ISerializable interfaces because ActLikeProxy does already implement them .Where(t => t.IsPublic && t != typeof(IDynamicMetaObjectProvider) && t != typeof(ISerializable)) .Select(MapInterface).ToArray(); if (interfaces.Length > 0) { return(Impromptu.DynamicActLike(wrapper, interfaces)); } return(wrapper); }
public override bool TryGetMember(GetMemberBinder binder, out object result) { if (binder == null) throw new ArgumentNullException("binder"); var dynamicObject = Model as RazorDynamicObject; if (dynamicObject != null) return dynamicObject.TryGetMember(binder, out result); Type modelType = Model.GetType(); var prop = modelType.GetProperty(binder.Name); if (prop == null) { if (!AllowMissingPropertiesOnDynamic) { result = null; return false; } result = new RazorDynamicObject() { AllowMissingPropertiesOnDynamic = AllowMissingPropertiesOnDynamic, Model = new object() }; return true; } object value = prop.GetValue(Model, null); if (value == null) { result = value; return true; } Type valueType = value.GetType(); result = (CompilerServicesUtility.IsAnonymousType(valueType)) ? new RazorDynamicObject { Model = value } : value; return true; }
/// <summary> /// Tries to find a member with the given name, the given arguments /// and the given parameter types and invokes that member. /// </summary> /// <param name="typeToSearch">the type we search for that member.</param> /// <param name="name">the name of the member</param> /// <param name="args">the arguments of the member</param> /// <param name="paramTypes">the type of the arguments of the member</param> /// <param name="result">the result of invoking the found member.</param> /// <returns>true if a member was found and invoked.</returns> private bool TryFindInvokeMember(Type typeToSearch, string name, object[] args, Type[] paramTypes, out object result) { var members = typeToSearch.GetMember(name, RazorDynamicObject.Flags); var found = false; result = null; foreach (var member in members) { var methodInfo = member as MethodInfo; if (!found && methodInfo != null && RazorDynamicObject.CompatibleWith(methodInfo.GetParameters(), paramTypes)) { result = methodInfo.Invoke(_component, args); found = true; break; } var property = member as PropertyInfo; if (!found && property != null) { var setMethod = property.GetSetMethod(true); if (setMethod != null && RazorDynamicObject.CompatibleWith(setMethod.GetParameters(), paramTypes)) { result = setMethod.Invoke(_component, args); found = true; break; } var getMethod = property.GetGetMethod(true); if (getMethod != null && RazorDynamicObject.CompatibleWith(getMethod.GetParameters(), paramTypes)) { result = getMethod.Invoke(_component, args); found = true; break; } } } return(found); }
public object GetResult(Invocation invocation) { (new PermissionSet(PermissionState.Unrestricted)).Assert(); object result = null; string name = invocation.Name.Name; object[] args = invocation.Args; Type[] paramTypes = args.Select(o => o.GetType()).ToArray(); try { if (invocation.Kind == InvocationKind.NotSet && invocation.Name.Name == "_BinaryOperator") { // We use that for operators var exp = (ExpressionType)args[0]; object other = args[1]; result = Impromptu.InvokeBinaryOperator(_component, exp, other); } else if (invocation.Kind == InvocationKind.NotSet && invocation.Name.Name == "_UnaryOperator") { // We use that for operators var exp = (ExpressionType)args[0]; result = Impromptu.InvokeUnaryOperator(exp, _component); } else { // First we try to resolve via DLR dynamic target = _component; result = invocation.InvokeWithStoredArgs(_component); } } catch (RuntimeBinderException) { // DLR doesn't like some kind of functions, // expecially because we have casted the component to object... bool found = false; switch (invocation.Kind) { case InvocationKind.Convert: var targetType = (Type)args[0]; bool tExplict = false; if (args.Length == 2) { tExplict = (bool)args[1]; } // try to find explicit or implicit operator. try { result = DynamicCast(_component, targetType); found = true; } catch (Exception) { found = false; } break; //case InvocationKind.IsEvent: //case InvocationKind.AddAssign: //case InvocationKind.SubtractAssign: //case InvocationKind.Invoke: //case InvocationKind.InvokeAction: //case InvocationKind.InvokeUnknown: //case InvocationKind.InvokeMember: // TODO: add testcase //case InvocationKind.InvokeMemberAction: // TODO: add testcase //case InvocationKind.GetIndex: // TODO: add testcase //case InvocationKind.SetIndex: // TODO: add testcase case InvocationKind.Get: case InvocationKind.Set: case InvocationKind.InvokeMemberUnknown: { if (!found) { if (!TryFindInvokeMember(_runtimeType, name, args, paramTypes, out result)) { // search all interfaces as well foreach (var @interface in _runtimeType.GetInterfaces().Where(i => i.IsPublic)) { if (TryFindInvokeMember(@interface, name, args, paramTypes, out result)) { found = true; break; } } } else { found = true; } } } break; default: break; } if (!found) { if (_allowMissing) { return(RazorDynamicObject.Create("", _allowMissing)); } throw; } } if (RazorDynamicObject.IsPrimitive(result)) { return(result); } else { return(RazorDynamicObject.Create(result, _allowMissing)); } }