public MvcFunctionBuilder RegisterAction <T>(string actionName, string functionName = null, string description = null) where T : Controller
        {
            var controllerType = typeof(T);

            Verify.That(IsController(controllerType), "Type '{0}' is not public or not its name does not have the 'Controller' ending", controllerType.FullName);

            //var methodInfo = StaticReflection.GetMethodInfo(method);

            string @namespace = null;
            string name       = null;

            if (string.IsNullOrWhiteSpace(functionName))
            {
                string controllerName = controllerType.FullName.Substring(0,
                                                                          controllerType.FullName.Length - "Controller".Length);


                if (string.Equals(actionName, "Index", StringComparison.OrdinalIgnoreCase))
                {
                    name       = actionName;
                    @namespace = controllerType.Namespace + "." + controllerName;
                }
                else
                {
                    name       = controllerName;
                    @namespace = controllerType.Namespace;
                }
            }
            else
            {
                ParseFunctionName(functionName, out @namespace, out name);
            }


            var function = new MvcActionFunction(controllerType, actionName, @namespace, name, description, this);

            MvcFunctionRegistry.Functions.Add(function);

            MvcFunctionProvider.Reload();

            return(new MvcFunctionBuilder(function));
        }
        public MvcFunctionBuilder RegisterController(Type controllerType, string functionName = null, string description = null)
        {
            string @namespace = null, name = null;

            if (functionName != null)
            {
                ParseFunctionName(functionName, out @namespace, out name);
            }

            var attribute = new C1FunctionAttribute
            {
                Namespace   = @namespace,
                Name        = name,
                Description = description
            };

            var function = RegisterController(controllerType, attribute, new List <ParameterProfile>());

            MvcFunctionProvider.Reload();

            return(new MvcFunctionBuilder(function));
        }
        public void AutoDiscoverFunctions(Assembly assembly)
        {
            foreach (var type in assembly.GetTypes().Where(IsController))
            {
                // Searching for [C1Function] attribute on controller or on its methods
                var attribute = type.GetCustomAttributes <C1FunctionAttribute>(false).SingleOrDefault();

                MvcControllerFunction controllerFunction = null;
                if (attribute != null)
                {
                    controllerFunction = RegisterController(type, attribute, null);
                }


                foreach (var method in type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
                {
                    var    actionNameAttribute = method.GetCustomAttributes <ActionNameAttribute>(false).SingleOrDefault();
                    string actionName          = actionNameAttribute != null ? actionNameAttribute.Name : method.Name;

                    MvcFunctionBase controlerToAttachUrlMapperTo = controllerFunction;
                    string          urlMapperAction = actionName;

                    attribute = method.GetCustomAttributes <C1FunctionAttribute>(false).SingleOrDefault();
                    if (attribute != null)
                    {
                        var routeAttribute = method.GetCustomAttributes <RouteAttribute>(false)
                                             .SingleOrDefaultOrException(
                            "Multiple [Route] attributes defined on method '{0}' of controller class '{1}'",
                            method.Name, type.FullName);

                        var parameters = routeAttribute != null?GetFunctionParameters(method, routeAttribute) : GetFunctionParameters(method);

                        var methodBasedMvcFunction = RegisterActionFunction(type, actionName, routeAttribute != null, attribute, parameters);

                        controlerToAttachUrlMapperTo = methodBasedMvcFunction;
                        urlMapperAction = null;
                    }

                    // Attaching url mappers
                    if (controlerToAttachUrlMapperTo != null)
                    {
                        var dynamicUrlMapperAttributes = method.GetCustomAttributes <DynamicUrlMapperAttribute>(false).ToList();
                        var globalUrlMapperAttributes  = method.GetCustomAttributes <GlobalUrlMapperAttribute>(false).ToList();

                        foreach (var mapperAttr in dynamicUrlMapperAttributes)
                        {
                            var mapper = new MvcFunctionDataUrlMapper(mapperAttr.DataType, null, urlMapperAction, mapperAttr.FieldName);
                            controlerToAttachUrlMapperTo.AssignDynamicUrlMapper(mapperAttr.DataType, mapper);
                        }

                        foreach (var mapperAttr in globalUrlMapperAttributes)
                        {
                            var mapper = new MvcFunctionDataUrlMapper(mapperAttr.DataType, mapperAttr.PageId, urlMapperAction, mapperAttr.FieldName);
                            DataUrls.RegisterGlobalDataUrlMapper(mapperAttr.DataType, mapper);
                        }
                    }
                }
            }

            MvcFunctionProvider.Reload();
        }