栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

.net core IOC(控制反转)、DI(依赖注入)

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

.net core IOC(控制反转)、DI(依赖注入)

文章目录
  • 一、什么是控制反转(Inversion of Control ,简称IOC)
    • 1.IOC代码层面解释:
    • 2.DI代码层面解释:
  • 二、为什么要使用IOC
    • 1.测试代码(耦合代码)
  • 三、IOC如何降低耦合
    • 1.情景再现:
    • 2.IOC实现原理
  • 四、 IOC模式中的容器
    • 1.容器的解释
    • 2. .net core 自带容器的使用

一、什么是控制反转(Inversion of Control ,简称IOC)

控制反转,是面向对象编程中的一种设计原则,可以减少代码之间的耦合度,其中最常见的方式叫做依赖注入(Dependency Injection , 简称DI)

1.IOC代码层面解释:

调用者不在创建(不自己new)被调用者的实例,而是交给容器去创建,这个就是控制反转

2.DI代码层面解释:

容器创建好实例在注入调用者的过程,就是依赖注入(比如:属性注入、构造函数注入等)。

二、为什么要使用IOC

我们常用的设计模式为接口驱动设计,接口驱动设计有很多好处,提供不同灵活的子类实现,
但是接口一定是需要实现的,也就是初始化实例一定会执行,
所以就会出现一些问题:多个子类按照一般的方法实现同一个接口,即会出现耦合

1.测试代码(耦合代码)

第一步: 新建一个.net core API程序ioc_demo

第二步:创建一个接口:ITestService.cs

using System;
namespace ioc_demo.@interface
{
    public interface ITestService
    {
        //声明一个属性一个方法
        int Count { get; }
        void Add();
    }
}

第三步:新建一个实现接口的类:TestServiceImpl.cs

using System;
using ioc_demo.@interface;

namespace ioc_demo.lmpl
{
    public class TestServiceImpl : ITestService
    {
        private int _count;
        public TestServiceImpl()
        {
            _count = 0;
            Console.WriteLine("服务创建");
        }

        public int Count => _count;

        public void Add()
        {
            _count++;
        }
    }
}

第四步:创建一个新的control:TestController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ioc_demo.@interface;
using ioc_demo.lmpl;
using Microsoft.AspNetCore.Mvc;

// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace ioc_demo.Controllers
{
    [Route("api/[controller]")]
    public class TestController : Controller
    {
        // GET: api/values
        [HttpGet]
        public Tuple Get()
        {
            ITestService testService = new TestServiceImpl(); //接口实现类,程序耦合
            int first = testService.Count;
            testService.Add();
            int second = testService.Count;
            Console.WriteLine(first);
            Console.WriteLine(second);
            return new Tuple(first, second);

        }
    }
}

三、IOC如何降低耦合 1.情景再现:

两个类互相调用,一般情况ClassA中使用带了ClassB中的对象或者属性方法,那么就需要在ClassA中显式的new一个ClassB

2.IOC实现原理

采用依赖注入技术之后,ClassA的代码只需要定义一个私有的ClassB对象,不要用通过实例化new出来这个ClassB,而是通过相关的容器控制程序将ClassB对象在容器中new出来并注入到ClassA类里的引用中。 具体的获取方法、对象获取时的状态则需要配置来制定

四、 IOC模式中的容器 1.容器的解释

IOC模式,系统通过引入实现了IOC模式的IOC容器,即可由IOC容器来管理对象的生命周期、依赖关系、从而使得应用程序的配置和依赖性规范与实际的应用程序代码分离。
最大的好处:修改程序组件间的配置,而不需要重新修改编译具体的代码

2. .net core 自带容器的使用
  1. AddTransient:瞬时的,每次访问构造一个

在Startup.cs类ConfigureServices中添加以下代码

public void ConfigureServices(IServiceCollection services)
        {

            services.AddControllers();
            services.AddTransient();//注入服务 瞬时模式
        }

将TestController.cs中代码替换为下列代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ioc_demo.@interface;
using ioc_demo.lmpl;
using Microsoft.AspNetCore.Mvc;

// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace ioc_demo.Controllers
{
    [Route("api/[controller]")]
    public class TestController : Controller
    {
        private ITestService _service;
        public TestController(ITestService testService)
        {
            _service = testService;
        }
        // GET: api/values
        [HttpGet]
        public Tuple Get()
        {
            //ITestService testService = new TestServiceImpl(); //接口实现类,程序耦合
            int first = _service.Count;
            _service.Add();
            int second = _service.Count;
            Console.WriteLine(first);
            Console.WriteLine(second);
            return new Tuple(first, second);

        }
    }
}

总结:每次访问接口,TestServiceImpl构造函数中都会执行Console.WriteLine("服务创建"); 符合瞬时创建构造函数的特性

  1. AddSingleton: 单例,全局只有一个

    在Startup.cs类ConfigureServices中替换以下代码

public void ConfigureServices(IServiceCollection services)
        {

            services.AddControllers();
            services.AddSingleton(); //注入服务  单例模式
        }

总结:每次访问接口,TestServiceImpl构造函数中都只会执行Console.WriteLine("服务创建");一次, 符合单例模式的特性

  1. AddScoped : 在同作用域、服务每次请求只创建一个

在Startup.cs类ConfigureServices中添加以下代码

public void ConfigureServices(IServiceCollection services)
        {

            services.AddControllers();
            services.AddScoped();//注入服务 作用域模式
        }

将TestController.cs中代码替换为下列代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ioc_demo.@interface;
using ioc_demo.lmpl;
using Microsoft.AspNetCore.Mvc;

// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace ioc_demo.Controllers
{
    [Route("api/[controller]")]
    public class TestController : Controller
    {
        private ITestService _service;
        public TestController(ITestService testService)
        {
            _service = testService;
        }
        // GET: api/values
        [HttpGet]
        public Tuple Get([FromServices]ITestService service)
        {
            //ITestService testService = new TestServiceImpl(); //接口实现类,程序耦合
            service.Add();
            int first = _service.Count;
            _service.Add();
            int second = _service.Count;
            Console.WriteLine(first); 
            Console.WriteLine(second);
            //如果返回1,2  说明service 与 _service是同一个对象
            return new Tuple(first, second);

        }
    }
}

总结:在此作用域使用服务,只会创建一个;

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/984935.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号