Example #1
0
 public FunctionDescriptor(MethodInfo method, ITriggerAttribute trigger, FunctionParameterBindings parameterBindings, IUserQueryActivator activator)
 {
     this.Method            = method;
     this.Trigger           = trigger;
     this.ParameterBindings = parameterBindings;
     this.Activator         = activator;
 }
Example #2
0
        public object[] Apply(FunctionParameterBindings parameterBindings)
        {
            var values = new object[parameterBindings.Arity];

            for (int i = 0; i < values.Length; i++)
            {
                var binding = parameterBindings.GetBinding(i);
                var value   = FindValue(binding.ParameterType);
                if (value == null)
                {
                    values[i] = binding.DefaultValue;
                }
                else
                {
                    values[i] = value;
                }
            }
            return(values);
        }
Example #3
0
        public static FunctionDescriptor Bind(MethodInfo m)
        {
            ITriggerAttribute trigger = null;

            foreach (var triggerAttributeType in _triggerAttributeTypes)
            {
                var t = (ITriggerAttribute)m.GetCustomAttribute(triggerAttributeType, false);
                if (t != null)
                {
                    if (trigger != null)
                    {
                        throw new ApplicationException($"Function '{m.Name}' cannot have multiple triggers.");
                    }
                    trigger = t;
                }
            }

            if (trigger == null)
            {
                return(null);
            }

            var parameters        = m.GetParameters();
            var parameterBindings = new FunctionParameterBindings(parameters.Length);

            foreach (var p in parameters)
            {
                var pt = p.ParameterType;
                if (parameterBindings.HasBinding(pt))
                {
                    throw new ApplicationException($"Function '{m.Name}' parameter '{p.Name}' type '{pt.FullName}' has already been bound once (you should remove this parameter).");
                }
                parameterBindings.Bind(pt, p.Position);
            }

            var triggerRequiredParameterTypes = trigger.GetRequiredParameterTypes();

            foreach (var triggerRequiredParameterType in triggerRequiredParameterTypes)
            {
                if (!parameterBindings.HasBinding(triggerRequiredParameterType))
                {
                    throw new ApplicationException($"Function '{m.Name}' is missing required parameter of type '{triggerRequiredParameterType}' (you need to add a parameter of this type).");
                }
            }

            var constructors = m.DeclaringType.GetConstructors();

            if (!(constructors.Length == 1))
            {
                throw new ApplicationException($"Declaring type '{m.DeclaringType}' of function '{m.Name}' should have exactly 1 constructor.");
            }

            IUserQueryActivator activator;

            var constructor           = constructors[0];
            var constructorParameters = constructor.GetParameters();

            switch (constructorParameters.Length)
            {
            case 0:
            {
                activator = new UserQueryActivator(m.DeclaringType);
                break;     // ok, parameterless
            }

            case 1:
            {
                var constructorParameter0 = constructorParameters[0];
                if (constructorParameter0.ParameterType == typeof(System.Data.IDbConnection))
                {
                    activator = new UserQueryWithConnectionActivator(m.DeclaringType);
                    break;     // ok, typed data context
                }
                goto default;
            }

            default:
                throw new ApplicationException($"Declaring type '{m.DeclaringType}' of function '{m.Name}' has an unsupported constructor signature.");
            }

            var f = new FunctionDescriptor(m, trigger, parameterBindings, activator);

            return(f);
        }