当前位置: 首页 > 科技观察

如何避免ASP.NETCore中的冗余DI代码?_0

时间:2023-03-15 13:50:18 科技观察

【.com速译】在Web应用中使用ASP.NETCore或ASP.NETCoreMVC处理控制器时,可能会遇到代码冗余。例如,您可能遇到过使用依赖注入(DI)来注入所需服务的控制器。如果注入依赖的代码在多个controller中复用,就会存在代码冗余,违反DRY原则。本文重点关注DI代码冗余,并展示如何构建自定义基础控制器以避免此类问题。要使用本文中提供的代码示例,您的系统上应安装VisualStudio2019。如果您尚未安装它,可以在此处下载VisualStudio2019。在VisualStudio中创建一个ASP.NETCoreMVC项目首先,让我们在VisualStudio2019中创建一个ASP.NETCore项目。按照这些步骤将在VisualStudio2019中创建一个新的ASP.NETCoreMVC项目。1.启动VisualStudio集成开发环境。2.单击创建新项目。3.在CreateNewProject窗口中,从显示的模板列表中选择ASP.NETCoreWebApp(Model-View-Controller)。4.单击下一步。5.在“配置新项目”窗口中,为新项目指定名称和位置。6.根据您的喜好选择“将解决方案和项目放在同一目录中”复选框。7.单击下一步。8.在出现的附加信息窗口中,从顶部的下拉列表中选择.NET5.0作为目标框架。将“身份验证类型”保留为“无”(默认值)。9.确保“启用Docker”、“配置HTTPS”和“启用Razor运行时编译”的复选框未选中,因为我们不会在此处使用任何这些功能。10.单击创建。将创建一个新的ASP.NETCoreMVC项目。在本文的其余部分,我们将使用该项目来处理依赖项注入。现在按照下面列出的步骤在您的项目中创建其他控制器。1.右键单击??控制器解决方案文件夹。2.选择添加->控制器。3.在AddNewScaffoldingItem对话框中,选择API作为模板(默认情况下会选择MVC)。4.选择“具有读/写操作的API控制器”项。5.单击添加。6.在出现的“添加新项”对话框中,为新控制器指定一个名称。7.单击添加。ASP.NETCoreController中内置的控制器基类有两个基类,ControllerBase和Controller。ControllerBase类实现IController接口并提供多个方法和属性的实现。它定义了一个名为ExecuteCore的抽象方法,用于定位操作方法并执行它。无论何时构建API,都应该使用ControllerBase。Controller类扩展了ControllerBase类,提供了ExecuteCore方法,并增加了View()和Redirect()等几个可以在控制器类中使用的方法。与ControllerBase一样,Controller类是支持视图的基控制器类。因此,无论何时在ASP.NETCoreMVC中创建控制器,都应该使用Controller类。ControllerBase类提供了与路由和HttpContext的必要集成,以便您可以利用它们。它还包含管理ViewData和TempData所需的代码。在ASP.NETCore中实现基控制器类当我们在ASP.NETCore中创建一个新的API控制器类时,它默认扩展了ControllerBase类。接下来,我们将创建基本控制器的实现。我们的基控制器类将扩展框架的ControllerBase类。这是我们将在这个例子中使用的实体类:publicclassOrder{publicintId{get;set;}publicintCustomerId{get;set;}publicstringAddress{get;set;}}现在用ProcessOrder方法语句创建下面的调用IOrderManager的接口。publicinterfaceIOrderManager{publicvoidProcessOrder(Orderorder);}接下来,创建一个扩展IOrderManager接口并实现ProcessOrder方法的OrderManager类。publicclassOrderManager:IOrderManager{publicvoidProcessOrder(Orderorder){thrownewSystem.NotImplementedException();}}以下代码片段展示了如何通过从ControllerBase类派生来创建基控制器类。[Route("api/[controller]")][ApiController]publicclassBaseController:ControllerBase{protectedreadonlyILogger_logger;protectedreadonlyIOrderManager_orderManager;publicBaseController(ILoggerlogger,IOrderManagerorderManager){_logger=logger;_orderManager=orderManager;}}ASPNETCore现在您可以创建控制器,这些控制器只是从我们刚刚创建的自定义基础控制器派生而来。以下代码片段显示了如何通过扩展刚创建的控制器基类来创建控制器类。[Route("api/[controller]")][ApiController]publicclassOrderController:BaseController{privatereadonlyILogger_logger;[HttpGet]publicstringGet(){return"OrderController";}[HttpPost]publicvoidProcessOrder(Orderorder){_orderManager.ProcessOrder(order);}}然而,你会发现上面的代码无法通过编译。下面是您将在VisualStudio中看到的错误:该错误指出您需要使用与BaseController类构造函数相同的参数来实现另一个参数构造函数。但为什么?如果您在所有扩展您创建的控制器基类的控制器中复制依赖项注入代码,那么您将无法达到扩展该类的目的。要解决此问题,您可以利用HttpContext.RequestServices.GetService扩展方法。请记住,如果您尝试在控制器的构造函数中访问HttpContext实例,该实例将为空。作为ASP.NETCore请求的一部分存在的服务可通过HttpContext.RequestServices集合进行访问。这意味着当您请求服务时,该请求将从该集合中解析。将HttpContext添加到ASP.NETCore中的基控制器类这是我们的BaseController类的更新源代码。publicabstractclassBaseController:ControllerBasewhereT:BaseController{privateILogger_logger;protectedILoggerLogger=>_logger??(_logger=HttpContext.RequestServices.GetService>());}OrderController类扩展这个抽象的BaseController类,如下面的代码片段所示。[Route("api/[controller]")][ApiController]publicclassOrderController:BaseController{privatereadonlyIOrderManager_orderManager;publicOrderController(IOrderManagerorderManager){_orderManager=orderManager;}[HttpGet]publicstringGet(){Logger.LogInformation("HelloWorld!");return"InsidetheGetmethodofOrderController";}[HttpPost]publicvoidProcessOrder(Orderorder){_orderManager.ProcessOrder(order);}}就是这样!OrderController可以采用Logger实例并使用构造函数注入来注入其他服务。最后记得在Startup类的ConfigureServices方法中注册你的服务,如下所示:构造函数来解决依赖关系,例如通过使用构造函数注入。这将帮助您创建更易于测试和维护的类。原标题:HowtoavoidredundantDIcodeinASP.NETCore,作者:JoydipKanjilal