c# - .NET 核心依赖注入与静态
问题描述
我正在使用.net core3 构建一个 API。
在控制器中,我曾经使用静态类从 sql 中获取信息列表或从 webservices 中获取一些结果。
但我认为使用依赖注入可能会更好。所以我将代码更改为使用 DI。
但我不确定这些变化实际上是否更好,如果是这样,为什么?
我能问一下它们有什么不同,哪一个更好吗?
原始代码:
public class TestController : Controller
{
[HttpGet("{id}")]
public async Task<IActionResult> Product(int id)
{
///SearchManager is static class, static GetProductCodesFromSearch method get list of productcode from sql
List<string> productCodes = SearchManager.GetProducCodeFromSearch();
//ProductManager is static class, GetProducts mehtod make a webrequest as parallel to some webservice get list of product
List<Product> products = await ProductManager.GetProducts();
....
return Json(new { success = true, message = "Ok" });
}
}
我更改了代码以使用 DI
public class TestController : Controller
{
private readonly ISearchService _searchService;
private readonly IProductService _productService;
public TestController( ISearchService searchService,IProductService productService)
{
_searchService = searchService;
_productService = productService;
}
[HttpGet("{id}")]
public async Task<IActionResult> Product(int id)
{
//searchservice class is not static class, not static method GetProductCodesFromSearch method get list of productcode from sql
List<string> productCodes = _searchService.GetProducCodeFromSearch();
// productservice is not static class, not static GetProducts mehtod make a webrequest as parallel to some webservice get list of product
List<Product> products = await _productService.GetProducts();
....
return Json(new { success = true, message = "Ok" });
}
}
在启动中
services.AddScoped<ISearchService, SearchService>();
services.AddScoped<IProductService, ProductService>();
解决方案
带DI的版本更好。有一些原因:
- 您可以注入不同的实现,而无需更改控制器代码
- 使用 DI 测试代码更容易(使用静态类通常是不可能的)
- 静态类大多是全局公共的。有状态的静态类可以像其他语言中的全局变量一样产生不可预测的问题
- 通过检查控制器很容易猜测控制器的部门
- 此外,使用 DI 控制数据库连接也不那么困难(例如,您可以使用存储库和工作单元模式,仅在需要时打开与数据库的连接)
- 使用 DI 可以很容易地扩展您的方法的行为。例如,您可能需要从本地缓存而不是 db 返回数据。使用 DI,可以使用装饰器为您的服务完成,而使用静态类,即使您只需要在代码的单个位置缓存,您也必须修改此类本身
另外我想补充一点,到处使用静态类不是 OOP 方法。所以我建议使用你的类和 DI 的实例
推荐阅读
- android - SDKManager:“错误:无法找到或加载主类 K”
- firebase - 如何在 firebase 托管中托管单页 webapp 的静态文件,并将 web API 部署在不同的服务器中
- java - 获取和设置参数弹出窗口?
- python-3.x - 为什么我的数据库中的信息没有打印出来?
- swift - 在 info.plist 中没有 HealthKit 的 ResearchKit
- sqlite - 来自数据库的数据未在列表视图颤动中获取/显示
- ios - IOS模拟器无法使用Apple ID登录
- javascript - 如何在运行时设置 React 的 PUBLIC_URL
- javascript - 验证 ReactJs 中的动态表单字段
- text - Photoshop 脚本/插件可以更快地修改文本