using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Reflection; using System.Web; using System.Web.Http; using System.Web.Http.Controllers; using System.Web.Http.Dispatcher; using System.Web.Http.Routing; namespace SwashbuckleEx.WebApiTest.Selectors { /// /// WebApi区域控制器选择器 /// public class AreaHttpControllerSelector : DefaultHttpControllerSelector { /// /// 区域路由变量名 /// private const string AreaRouteVariableName = "area"; /// /// Http配置 /// private readonly HttpConfiguration _configuration; /// /// Api控制器类型字典 /// private readonly Lazy> _apiControllerTypes; /// /// 初始化一个类型的实例 /// /// Http配置 public AreaHttpControllerSelector(HttpConfiguration configuration) : base(configuration) { _configuration = configuration; _apiControllerTypes = new Lazy>(GetControllerTypes); } /// /// 获取控制器类型字典 /// /// private static ConcurrentDictionary GetControllerTypes() { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); Dictionary types = assemblies .SelectMany(a => a .GetTypes().Where(t => !t.IsAbstract && t.Name.EndsWith(ControllerSuffix, StringComparison.OrdinalIgnoreCase) && typeof(IHttpController).IsAssignableFrom(t))) .ToDictionary(t => t.FullName, t => t); return new ConcurrentDictionary(types); } /// /// 由Http请求获取控制台描述信息 /// /// Http请求消息 /// public override HttpControllerDescriptor SelectController(HttpRequestMessage request) { return GetApiController(request); } /// /// 获取Api控制器 /// /// Http请求消息 /// private HttpControllerDescriptor GetApiController(HttpRequestMessage request) { string areaName = GetAreaName(request); string controllerName = GetControllerName(request); if (controllerName == null) { throw new InvalidOperationException("获取的Api控制器名称为空"); } Type type = GetControllerType(areaName, controllerName); return new HttpControllerDescriptor(_configuration, controllerName, type); } /// /// 获取区域名 /// /// Http请求消息 /// private static string GetAreaName(HttpRequestMessage request) { IHttpRouteData data = request.GetRouteData(); object areaName; if (data.Route == null || data.Route.DataTokens == null) { if (data.Values.TryGetValue(AreaRouteVariableName, out areaName)) { return areaName.ToString(); } return null; } return data.Route.DataTokens.TryGetValue(AreaRouteVariableName, out areaName) ? areaName.ToString() : null; } /// /// 获取控制器类型 /// /// 区域名 /// 控制器名 /// private Type GetControllerType(string areaName, string controllerName) { IEnumerable> query = _apiControllerTypes.Value.AsEnumerable(); query = string.IsNullOrWhiteSpace(areaName) ? query.WithoutAreaName() : query.ByAreaName(areaName); Type type = query.ByControllerName(controllerName).Select(m => m.Value).SingleOrDefault(); if (type == null) { throw new Exception(string.Format("未找到名称为“{0}”的Api控制器",controllerName)); } return type; } } }