如何为.NET Framework与.NET Core创建通用API控制器?
跨.NET Framework与.NET Core的共享API控制器实现方案
针对你需要同时支持.NET Framework 4.7.2(OWIN自托管)和.NET Core(ASP.NET Core WebAPI)的REST API场景,且核心逻辑基于.NET Standard 2.0、使用Autofac依赖注入的需求,以下是无需重复编写控制器的可行方案:
核心思路:业务逻辑与控制器解耦
将API的核心业务逻辑抽离到.NET Standard 2.0类库中,两个平台的控制器仅作为路由适配层,负责处理各自框架的请求/响应格式,核心逻辑只维护一份,从根源上避免路由不匹配、代码重复的问题。
步骤1:在.NET Standard中封装核心业务处理类
把原来控制器中的业务逻辑迁移到独立的处理类中,依赖注入的服务(如IDebuggingLevelUtility、日志组件)直接注入到该类:
// .NET Standard 2.0 类库中的核心处理类 public class DebuggingApiHandler { private readonly ILogger _logger; private readonly IDebuggingLevelUtility _debugging; public DebuggingApiHandler(ILogger logger, IDebuggingLevelUtility debugging) { _logger = logger; _debugging = debugging; } // 获取日志级别逻辑 public string GetLoggerLevel() { try { return _debugging.Level.ToString(); } catch (Exception ex) { _logger.LogError(ex, "获取日志级别失败"); throw; // 抛出异常由上层控制器处理响应 } } // 修改日志级别逻辑 public string ChangeLoggerLevel(LogEventLevel level) { try { _logger.LogWarning("调试级别变更:{current} => {new}", _debugging.Level, level); _debugging.ChangeDebugLevel(level); return _debugging.Level.ToString(); } catch (Exception ex) { _logger.LogError(ex, "修改日志级别失败"); throw; } } }
步骤2:统一路由配置(避免路由不匹配)
在.NET Standard中定义静态路由常量,确保两个平台的路由配置完全一致:
// .NET Standard 2.0 类库中的路由常量类 public static class ApiRouteConstants { public const string DebuggingBase = "api/debugging"; public const string DebuggingGet = ""; public const string DebuggingPostLevel = "{level}"; }
步骤3:各平台控制器实现(仅做适配)
ASP.NET Core 控制器
继承ControllerBase,注入核心处理类,调用业务逻辑并返回符合ASP.NET Core规范的ActionResult:
[ApiController] [Route(ApiRouteConstants.DebuggingBase)] public class DebuggingController : ControllerBase { private readonly DebuggingApiHandler _apiHandler; // 通过Autofac注入依赖 public DebuggingController(ILogger<DebuggingController> logger, IDebuggingLevelUtility debugging) { _apiHandler = new DebuggingApiHandler(logger, debugging); // 也可直接通过Autofac注册DebuggingApiHandler,实现直接注入 } [HttpGet(ApiRouteConstants.DebuggingGet)] public ActionResult<string> GetLoggerLevel() { try { return _apiHandler.GetLoggerLevel(); } catch { return NotFound(); } } [HttpPost(ApiRouteConstants.DebuggingPostLevel)] [ProducesResponseType(typeof(string), 200)] [ProducesResponseType(typeof(BadRequestResult), 400)] public ActionResult<string> PostLoggerLevel(LogEventLevel level) { try { return _apiHandler.ChangeLoggerLevel(level); } catch { return BadRequest(); } } }
.NET Framework OWIN 控制器
继承ApiController,同样注入核心处理类,返回符合Web API 2规范的IHttpActionResult:
[RoutePrefix(ApiRouteConstants.DebuggingBase)] public class DebuggingController : ApiController { private readonly DebuggingApiHandler _apiHandler; public DebuggingController(ILogger logger, IDebuggingLevelUtility debuggingLevelUtility) { _apiHandler = new DebuggingApiHandler(logger, debuggingLevelUtility); } [HttpGet] [Route(ApiRouteConstants.DebuggingGet)] public IHttpActionResult GetLoggerLevel() { try { return Ok(_apiHandler.GetLoggerLevel()); } catch { return NotFound(); } } [HttpPost] [Route(ApiRouteConstants.DebuggingPostLevel)] public IHttpActionResult PostLoggerLevel(LogEventLevel level) { try { return Ok(_apiHandler.ChangeLoggerLevel(level)); } catch { return BadRequest(); } } }
步骤4:Autofac依赖注入配置
在两个平台的启动类中,注册核心处理类DebuggingApiHandler:
.NET Core 配置(Startup.cs)
public void ConfigureContainer(ContainerBuilder builder) { // 注册核心处理类,按请求生命周期实例化 builder.RegisterType<DebuggingApiHandler>().InstancePerRequest(); // 注册其他服务(如IDebuggingLevelUtility、日志组件) builder.RegisterType<DebuggingLevelUtility>().As<IDebuggingLevelUtility>().SingleInstance(); }
.NET Framework OWIN 配置(Startup.cs)
public void Configuration(IAppBuilder app) { var config = new HttpConfiguration(); var builder = new ContainerBuilder(); // 注册Web API控制器 builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); // 注册核心处理类 builder.RegisterType<DebuggingApiHandler>().InstancePerRequest(); // 注册其他服务 builder.RegisterType<DebuggingLevelUtility>().As<IDebuggingLevelUtility>().SingleInstance(); var container = builder.Build(); config.DependencyResolver = new AutofacWebApiDependencyResolver(container); app.UseAutofacMiddleware(container); app.UseAutofacWebApi(config); app.UseWebApi(config); }
方案优势
- 核心逻辑单一源:业务逻辑仅在.NET Standard类库中维护,避免重复编写带来的不一致问题
- 路由统一可控:通过静态常量确保两个平台路由完全匹配
- 适配成本低:控制器仅做框架层的请求/响应适配,代码量极少
- 长期兼容:.NET Framework版本停止维护后,可直接移除OWIN相关代码,保留ASP.NET Core实现即可
内容的提问来源于stack exchange,提问作者Eric Williams
相关产品推荐
相关产品推荐

