• .net 5.0


     1、依赖注入
     1.1、依赖

      人与人之间都有依赖(尤其我,就是离不开女人哈哈)何况软件呢?所谓依赖就是:当一个类需要另一个类协作来完成工作的时候就产生了依。比如用户登录,我们在控制器中UserController要完成用户登录、注册、修改密码等等事情、其中操作到数据库的(登录)我们用EF来完成,这里我们封装了一个EFLogin,这里的UserController就有一个ILogin的依赖。需要知道的是这里依赖于一个抽象为不是具体的某一个实现,所以给EFLogin定义了一个接口ILogin抽象了EFLogin的行为:

     

     1.2、注入

       注入体现的是一个IOC(控制反转的的思想)

    public interface IUser
    {
        string BB();
    }
    public class User : IUser
    {
        public string BB()
        {
            return "LP整天只会BB";
        }
    }
    public class ShowInfo
    {
        IUser user = new User();
        public void UserBB()
        {
            user.BB();
        }
    }
    

      当我们调用ShowInfo的时候,是通过IUser接口实例化一个User类去实现其方法的这叫控制正传, 但是大湿兄说,我们不应该创建User类,而是让调用者给你传递,于是你通过构造函数让外界把这两个依赖给你。把依赖的创建丢给其它人。自己只负责使用,其它人丢给你依赖的这个过程理解为注入其它人丢给你依赖的这个过程理解为注入。也叫控制反转(IOC)

    public interface IUser
    {
        string BB();
    }
    public class User : IUser
    {
        public string BB()
        {
            return "LP整天只会BB";
        }
    }   
    public class ShowInfo2
    {
        private readonly IUser _user;
        public ShowInfo2 (IUser user)
        {
            _user = user;
        }
        public void UserBB()
        {
            _user.BB();
        }
    }
     1.3、为什么要使用依赖注入

      使用依赖注入我们可以很好的管理类跟类之间的依赖,在我们设计应用程序的时候遵循这几原则,确保代码的可维护性和扩展性;另外在Core的架构中依赖注入提供了对象创建和生命周期管理的核心能力,各个组件之间的相互协作也是由依赖注入框架来实现的

     2、服务生命周期
     2.1、三种生命周期说明

     在ConfigureServices方法中的容器注册每个应用程序的服务,Asp.Core都可以为每个应用程序提供三种服务生命周期:
      Transient(暂时):每次请求都会创建一个新的实例。这种生命周期最适合轻量级,无状态服务。
      Scoped(作用域):在同一个作用域内只初始化一个实例 ,可以理解为每一个请求只创建一个实例,同一个请求会在一个作用域内。在Scooped的生存周期内,如果容器释放 它也就被释放了
      Singleton(单例):整个应用程序生命周期以内只创建一个实例,后续每个请求都使用相同的实例。如果应用程序需要单例行为,建议让服务容器管理服务的生命周期,而不是在自己的类中实现单例模式。

     2.2、三种生命周期说明

     单例的没有改变所以

      Transient(暂时):每次调用服务的时候都会创建一个新的实例

       Scoped(作用域):一次请求(Action)内对象实例是相同的,但每次请求会产生一个新实例。

      Singleton(单例):首次请求初始化同一个实例,后续每次请求都使用同一个实例。相当于在整个应用Application中只实例化一次实例,常见的单例模式。

     2.3、测试案例

     上面描述的比较抽象,不容易理解,用实例来讲解会比较直观。

     下面通过具体的例子进行演示。

     定义三个空的接口:IArticleService、IProductService、IUserService

     然后定义三个实现:ArticleService、ProductService、UserService

     1.将接口和实现注入到DI容器

     在StartUp类的ConfigureServices方法添加下图代码

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
        services.Configure<Test>(Configuration.GetSection("Test"));
    
        //演示生命周期
        services.AddTransient<IUserService, UserService>();
        services.AddScoped<IArticleService, ArticleService>();
        services.AddSingleton<IProductService, ProductService>();
    }
    

     2.添加私有字段,在测试Controller:LifeTimeController中添加下图代码

    private readonly IUserService _userService1;
    private readonly IUserService _userService2;
    private readonly IArticleService _articleService1;
    private readonly IArticleService _articleService2;
    private readonly IProductService _productService1;
    private readonly IProductService _productService2;
    

     3.添加构造方法

    public LifeTimeController(
        IUserService userService1, IUserService userService2,
        IArticleService articleService1, IArticleService articleService2,
        IProductService productService1, IProductService productService2
    )
    {
        _userService1 = userService1;
        _userService2 = userService2;
        _articleService1 = articleService1;
        _articleService2 = articleService2;
        _productService1 = productService1;
        _productService2 = productService2;
    }
    

     4.添加测试代码

    public IActionResult Index()
    {
        var sb = new StringBuilder();
        sb.Append("transient1:" + _userService1.GetHashCode() + "<br />");
        sb.Append("transient2:" + _userService2.GetHashCode() + "<br />");
        sb.Append("scope1:" + _articleService1.GetHashCode() + "<br />");
        sb.Append("scope2:" + _articleService2.GetHashCode() + "<br />");
        sb.Append("singleton1:" + _productService1.GetHashCode() + "<br />");
        sb.Append("singleton2:" + _productService2.GetHashCode() + "<br />");
                
        Response.ContentType = "text/html";
        return Content(sb.ToString());
    }

    5.执行结果

    第一次刷新:

    transient1:66454027
    transient2:35021870
    scope1:38350037
    scope2:38350037
    singleton1:4417230
    singleton2:4417230

    第二次刷新:

    transient1:103653
    transient2:5079042
    scope1:47546512
    scope2:47546512
    singleton1:4417230
    singleton2:4417230

    可见

    transient类型的生命周期,每次使用都不一样,不同的类或不同的方法使用都不一样

    scope类型的生命周期,在同一个请求内是一样的

    singleton类型的生命周期,每次请求都是一样的

    所以理解了生命周期的作用,我们在开发的时候就可以根据需要对不同的服务选择不同的生命周期了。

  • 相关阅读:
    闭包
    值类型和引用类型的区别?
    计算机基础知识和基本操作
    Git常用命令
    任务八
    CSS任务七
    CSS任务六
    MySql+EF6,不能选实体框架6.x或者闪退
    以一定的格式生成最新的数据库流水号
    layui父窗体获取弹出窗体元素
  • 原文地址:https://www.cnblogs.com/gygtech/p/14792055.html
Copyright © 2020-2023  润新知