private MvcControllerFunction RegisterController(Type controllerType, C1FunctionAttribute attribute, IEnumerable <ParameterProfile> functionParameters)
        {
            var controllerDescriptor = new ReflectedControllerDescriptor(controllerType);

            string @namespace  = String.IsNullOrEmpty(attribute.Namespace) ? controllerDescriptor.ControllerType.Namespace : attribute.Namespace;
            string name        = String.IsNullOrEmpty(attribute.Name) ? controllerDescriptor.ControllerName : attribute.Name;
            string description = attribute.Description ?? String.Empty;

            var function = new MvcControllerFunction(controllerDescriptor, @namespace, name, description, this);

            if (functionParameters != null)
            {
                foreach (var param in functionParameters)
                {
                    function.AddParameter(param);
                }
            }

            MvcFunctionRegistry.Functions.Add(function);

            return(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();
        }