.NET Core 依赖注入与静态

dbe*_*eon 3 c# static dependency-injection .net-core asp.net-core

我正在使用 .net core3 构建 API。

在控制器中,我曾经使用静态类从 sql 获取信息列表或从 web 服务获取一些结果。

但我认为使用依赖注入可能会更好。所以我修改了代码以使用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" });
        }
    }
Run Code Online (Sandbox Code Playgroud)

我更改了代码以使用 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" });
        }
    }
Run Code Online (Sandbox Code Playgroud)

启动中

services.AddScoped<ISearchService, SearchService>();
services.AddScoped<IProductService, ProductService>();
Run Code Online (Sandbox Code Playgroud)

ing*_*var 9

带DI的版本更好。有一些原因:

  1. 您可以注入不同的实现,而无需更改控制器代码
  2. 使用 DI 测试代码不太困难(使用静态类通常是不可能的)
  3. 静态类大多是全局公共的。有状态静态类可能像其他语言中的全局变量一样,可能会产生不可预测的问题
  4. 通过检查控制器的构造函数很容易猜测控制器的依赖关系
  5. 此外,使用 DI 控制数据库连接也不太困难(例如,您可以使用存储库和工作单元模式,仅在需要时打开与数据库的连接)
  6. 使用 DI,可以轻松扩展方法的行为。例如,您可能需要从本地缓存而不是数据库返回数据。使用 DI,可以使用服务的装饰器来完成,而使用静态类,即使您只需要在代码的单个位置进行缓存,您也必须修改此类本身

另外我想补充一点,到处使用静态类不是 OOP 方法。所以我建议改用类和 DI 的实例