コード例 #1
0
        public void MethodMissing(object source, MethodMissingParameters missingParameters)
        {
            if (PropertySpec == null)
            {
                return;
            }

            var methodName = missingParameters.MethodName;

            // Search for the getter
            var aliasMatches = (from alias in PropertySpec.Aliases
                                let currentMethodName = string.Format("get_{0}", alias)
                                                        where currentMethodName == methodName
                                                        select alias).Count();

            var getterName = string.Format("get_{0}", PropertySpec.PropertyName);

            if (methodName != getterName && aliasMatches == 0)
            {
                return;
            }

            if (!PropertySpec.CanRead)
            {
                throw new InvalidOperationException(string.Format("The property '{0}' does not allow reads", PropertySpec.PropertyName));
            }

            var behavior = PropertySpec.Behavior;

            missingParameters.ReturnValue = behavior.GetValue(source, PropertySpec.PropertyName, PropertySpec.PropertyType);
            missingParameters.Handled     = true;
        }
コード例 #2
0
        private void InvokeMethodImplementation(object source, MethodMissingParameters missingParameters, string currentMethodName)
        {
            missingParameters.Handled = true;

            var body = MethodSpec.MethodBody;

            if (body == null)
            {
                throw new NotImplementedException(string.Format("The method '{0}' does not have an implementation", currentMethodName));
            }

            var signature = new MethodSignature(MethodSpec.ParameterTypes, MethodSpec.ReturnType);

            missingParameters.ReturnValue = body.Invoke(source, MethodSpec.MethodName,
                                                        signature, missingParameters.Arguments);

            if (missingParameters.ReturnValue == null || MethodSpec.ReturnType == typeof(void))
            {
                return;
            }

            // Verify that the return value is compatible with the return type
            var actualReturnType = missingParameters.ReturnValue.GetType();

            if (!MethodSpec.ReturnType.IsAssignableFrom(actualReturnType))
            {
                throw new InvalidReturnTypeException(MethodSpec.MethodName, MethodSpec.ReturnType, actualReturnType);
            }
        }
コード例 #3
0
        public void MethodMissing(object source, MethodMissingParameters missingParameters)
        {
            if (PropertySpec == null)
                return;

            var arguments = missingParameters.Arguments;
            if (arguments.Length != 1)
                return;

            var setterName = string.Format("set_{0}", PropertySpec.PropertyName);

            var aliasMatches = (from alias in PropertySpec.Aliases
                                let currentMethodName = string.Format("set_{0}", alias)
                                where currentMethodName == missingParameters.MethodName
                                select alias).Count();

            if (missingParameters.MethodName != setterName &&
                aliasMatches == 0)
                return;

            // Match the runtime argument type
            var argumentType = arguments[0] == null ? typeof(void) : arguments[0].GetType();

            if (argumentType != PropertySpec.PropertyType)
                return;

            if (!PropertySpec.CanWrite)
                throw new InvalidOperationException(string.Format("The property '{0}' does not allow writes", PropertySpec.PropertyName));

            // Set the property value
            var behavior = PropertySpec.Behavior;
            behavior.SetValue(source, PropertySpec.PropertyName, PropertySpec.PropertyType, arguments[0]);

            missingParameters.Handled = true;
        }
コード例 #4
0
        public void MethodMissing(object source, MethodMissingParameters missingParameters)
        {
            if (MethodSpec == null)
                return;

            var currentMethodName = missingParameters.MethodName;
            // Make sure that the method name matches either the
            // actual method name or a name from the list of method aliases
            var names = new List<string>();
            names.Add(MethodSpec.MethodName);
            names.AddRange(MethodSpec.Aliases);

            var isMatch = names.Contains(currentMethodName);
            if (!isMatch)
                return;

            // Match the parameter count
            var parameterCount = missingParameters.Arguments == null ? 0 : missingParameters.Arguments.Length;

            if (parameterCount != MethodSpec.ParameterTypes.Count)
                return;

            // Match the parameter types
            var isCompatible = true;
            var index = 0;
            foreach (var parameterType in MethodSpec.ParameterTypes)
            {
                Type argumentType = null;
                var currentArgument = missingParameters.Arguments[index++];

                if (currentArgument != null)
                    argumentType = currentArgument.GetType();

                if (argumentType == null)
                    continue;

                // Match the parameter type with the argument type
                // Note: Covariant typing is enabled by default
                if (parameterType.IsAssignableFrom(argumentType))
                    continue;

                isCompatible = false;
                break;
            }

            if (!isCompatible)
                return;

            InvokeMethodImplementation(source, missingParameters, currentMethodName);
        }
コード例 #5
0
        public void MethodMissing(object source, MethodMissingParameters missingParameters)
        {
            if (PropertySpec == null)
            {
                return;
            }

            var arguments = missingParameters.Arguments;

            if (arguments.Length != 1)
            {
                return;
            }

            var setterName = string.Format("set_{0}", PropertySpec.PropertyName);

            var aliasMatches = (from alias in PropertySpec.Aliases
                                let currentMethodName = string.Format("set_{0}", alias)
                                                        where currentMethodName == missingParameters.MethodName
                                                        select alias).Count();

            if (missingParameters.MethodName != setterName &&
                aliasMatches == 0)
            {
                return;
            }

            // Match the runtime argument type
            var argumentType = arguments[0] == null ? typeof(void) : arguments[0].GetType();

            if (argumentType != PropertySpec.PropertyType)
            {
                return;
            }

            if (!PropertySpec.CanWrite)
            {
                throw new InvalidOperationException(string.Format("The property '{0}' does not allow writes", PropertySpec.PropertyName));
            }

            // Set the property value
            var behavior = PropertySpec.Behavior;

            behavior.SetValue(source, PropertySpec.PropertyName, PropertySpec.PropertyType, arguments[0]);

            missingParameters.Handled = true;
        }
コード例 #6
0
        public virtual void MethodMissing(object source, MethodMissingParameters missingParameters)
        {
            var callbacks = GetCallbacks();

            if (callbacks == null)
            {
                return;
            }

            foreach (var callback in callbacks)
            {
                if (missingParameters.Handled)
                {
                    return;
                }

                callback.MethodMissing(source, missingParameters);
            }
        }
コード例 #7
0
        public void MethodMissing(object source, MethodMissingParameters missingParameters)
        {
            if (PropertySpec == null)
                return;

            var methodName = missingParameters.MethodName;

            // Search for the getter
            var aliasMatches = (from alias in PropertySpec.Aliases
                                let currentMethodName = string.Format("get_{0}", alias)
                                where currentMethodName == methodName
                                select alias).Count();

            var getterName = string.Format("get_{0}", PropertySpec.PropertyName);
            if (methodName != getterName && aliasMatches == 0)
                return;

            if (!PropertySpec.CanRead)
                throw new InvalidOperationException(string.Format("The property '{0}' does not allow reads", PropertySpec.PropertyName));

            var behavior = PropertySpec.Behavior;
            missingParameters.ReturnValue = behavior.GetValue(source, PropertySpec.PropertyName, PropertySpec.PropertyType);
            missingParameters.Handled = true;
        }
コード例 #8
0
        public void MethodMissing(object source, MethodMissingParameters missingParameters)
        {
            if (MethodSpec == null)
            {
                return;
            }

            var currentMethodName = missingParameters.MethodName;
            // Make sure that the method name matches either the
            // actual method name or a name from the list of method aliases
            var names = new List <string>();

            names.Add(MethodSpec.MethodName);
            names.AddRange(MethodSpec.Aliases);

            var isMatch = names.Contains(currentMethodName);

            if (!isMatch)
            {
                return;
            }

            // Match the parameter count
            var parameterCount = missingParameters.Arguments == null ? 0 : missingParameters.Arguments.Length;

            if (parameterCount != MethodSpec.ParameterTypes.Count)
            {
                return;
            }

            // Match the parameter types
            var isCompatible = true;
            var index        = 0;

            foreach (var parameterType in MethodSpec.ParameterTypes)
            {
                Type argumentType    = null;
                var  currentArgument = missingParameters.Arguments[index++];

                if (currentArgument != null)
                {
                    argumentType = currentArgument.GetType();
                }

                if (argumentType == null)
                {
                    continue;
                }

                // Match the parameter type with the argument type
                // Note: Covariant typing is enabled by default
                if (parameterType.IsAssignableFrom(argumentType))
                {
                    continue;
                }

                isCompatible = false;
                break;
            }

            if (!isCompatible)
            {
                return;
            }

            InvokeMethodImplementation(source, missingParameters, currentMethodName);
        }
コード例 #9
0
        private void InvokeMethodImplementation(object source, MethodMissingParameters missingParameters, string currentMethodName)
        {
            missingParameters.Handled = true;

            var body = MethodSpec.MethodBody;

            if (body == null)
                throw new NotImplementedException(string.Format("The method '{0}' does not have an implementation", currentMethodName));

            var signature = new MethodSignature(MethodSpec.ParameterTypes, MethodSpec.ReturnType);

            missingParameters.ReturnValue = body.Invoke(source, MethodSpec.MethodName,
                signature, missingParameters.Arguments);

            if (missingParameters.ReturnValue == null || MethodSpec.ReturnType == typeof(void))
                return;

            // Verify that the return value is compatible with the return type
            var actualReturnType = missingParameters.ReturnValue.GetType();

            if (!MethodSpec.ReturnType.IsAssignableFrom(actualReturnType))
                throw new InvalidReturnTypeException(MethodSpec.MethodName, MethodSpec.ReturnType, actualReturnType);
        }