/// <summary> /// Register controller factory data<br/> /// 注册控制器工厂函数<br/> /// </summary> public virtual void RegisterController(ContainerFactoryData factoryData) { // Get all public methods with ActionAttribute var type = factoryData.ImplementationTypeHint; var factory = (Func <IController>)factoryData.GenericFactory; foreach (var method in type.FastGetMethods( BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public)) { // Get action attributes var actionAttributes = method.GetCustomAttributes <ActionAttribute>(); if (!actionAttributes.Any()) { continue; } // Build action var action = factory.BuildActionDelegate(method); // Apply action filters var filterAttributes = method.GetCustomAttributes <ActionFilterAttribute>(); foreach (var filterAttribute in filterAttributes) { action = filterAttribute.Filter(action); } // Register action foreach (var attribute in actionAttributes) { RegisterAction(attribute.Path, attribute.Method, action, attribute.OverrideExists); } } }
/// <summary> /// Register controller type, reuse type will be Transient<br/> /// 注册控制器类型, 重用类型是Transient<br/> /// </summary> public virtual void RegisterController <T>() { var genericFactory = Application.Ioc.GenericBuildAndWrapFactory <T>(ReuseType.Transient); var objectFactory = new Func <object>(() => genericFactory()); var factoryData = new ContainerFactoryData(genericFactory, objectFactory, typeof(T)); RegisterController(factoryData); }
/// <summary> /// Register controller type, reuse type will be Transient<br/> /// 注册控制器类型, 重用类型是Transient<br/> /// </summary> public virtual void RegisterController(Type type) { Application.Ioc.NonGenericBuildAndWrapFactory( type, ReuseType.Transient, out var genericFactory, out var objectFactory); var factoryData = new ContainerFactoryData(genericFactory, objectFactory, type); RegisterController(factoryData); }
/// <summary> /// Register controller instance, reuse type will be Singleton<br/> /// 注册控制器实例, 重用类型是Singleton<br/> /// </summary> public virtual void RegisterController(IController controller) { var factoryData = new ContainerFactoryData( (c, s) => controller, ReuseType.Singleton, controller.GetType()); RegisterController(factoryData); }
/// <summary> /// Register controller type, reuse type will be Transient<br/> /// 注册控制器类型, 重用类型是Transient<br/> /// </summary> public virtual void RegisterController(Type type) { var factoryData = new ContainerFactoryData( ContainerFactoryBuilder.BuildFactory(type), ReuseType.Transient, type); RegisterController(factoryData); }
/// <summary> /// Register controller instance, reuse type will be Singleton<br/> /// 注册控制器实例, 重用类型是Singleton<br/> /// </summary> public virtual void RegisterController(IController controller) { Application.Ioc.NonGenericWrapFactory( controller.GetType(), () => controller, ReuseType.Transient, out var genericFactory, out var objectFactory); var factoryData = new ContainerFactoryData( genericFactory, objectFactory, controller.GetType()); RegisterController(factoryData); }
/// <summary> /// Register controller factory data<br/> /// 注册控制器工厂函数<br/> /// Rules:<br/> /// Class without [ActionBase], method with [Action("abc")] => /abc (for backward compatibility)<br/> /// Class without [ActionBase], method without [Action] => /$controller/$action<br/> /// Class without [ActionBase], method Index without [Action] => /$controller, /$controller/Index<br/> /// Class with [ActionBase("abc")], method with [Action("index")] => /abc/index<br/> /// Class with [ActionBase("abc")], method without [Action] => /abc/$action<br/> /// Class with [ActionBase("abc")], method Index without [Action] => /abc, /abc/Index<br/> /// </summary> public virtual void RegisterController(ContainerFactoryData factoryData) { var type = factoryData.ImplementationTypeHint; var factory = (Func <IController>)factoryData.GenericFactory; // Calculate path base from attribute or controller name - suffix var actionBaseAttribute = type.GetCustomAttribute <ActionBaseAttribute>(); string pathBase; if (actionBaseAttribute?.PathBase != null) { pathBase = actionBaseAttribute.PathBase.TrimEnd('/'); } else { pathBase = type.Name.EndsWith(ControllerSuffix) ? type.Name.Substring(0, type.Name.Length - ControllerSuffix.Length) : type.Name; } foreach (var method in type.FastGetMethods( BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly)) { // Ignore special and void methods if (method.IsSpecialName || method.ReturnType == typeof(void)) { continue; } // Get action attributes var actionAttributes = method.GetCustomAttributes <ActionAttribute>(); if (!actionAttributes.Any()) { if (method.Name == IndexMethodName) { actionAttributes = new[] { new ActionAttribute(), new ActionAttribute("") }; } else { actionAttributes = new[] { new ActionAttribute() }; } } // Build action var action = factory.BuildActionDelegate(method); // Apply action filters var filterAttributes = method.GetCustomAttributes <ActionFilterAttribute>(); foreach (var filterAttribute in filterAttributes) { action = filterAttribute.Filter(action); } // Register action foreach (var attribute in actionAttributes) { string path; if (actionBaseAttribute == null) { if (attribute.Path != null) { path = attribute.Path; } else { path = pathBase + "/" + method.Name; } } else { if (attribute.Path != null) { path = pathBase + "/" + attribute.Path.TrimStart('/'); } else { path = pathBase + "/" + method.Name; } } var httpMethod = attribute.Method ?? HttpMethods.GET; RegisterAction(path, httpMethod, action, attribute.OverrideExists); } } }