zoukankan      html  css  js  c++  java
  • ASP.NET Core框架学习之依赖注入

    ASP.NET Core支持依赖项注入(DI)软件设计模式,这是一种用于在类及其依赖项之间实现控制反转(IoC)的技术

    引用nuget包

    .net core使用了接口与实现分离的设计模式,这样的好处是第三方的Ioc容器只需要引用Microsoft.Extensions.DependencyInjection.Abstractions包,并实现其中的接口,就可以与.net core框架完美兼容了。

    Microsoft.Extensions.DependencyInjection.Abstractions
    Microsoft.Extensions.DependencyInjection 

    简单示例 

      声明接口及其实现类

    //声明一个接口
    public interface IVipService    
    {}
    //声明IVipService接口的实现类
    public class VipService : IVipService 
    {} 

      在Startup.cs的ConfigureServices方法中将接口实现添加到Ioc容器

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddScoped<IVipService, VipService>();
        services.AddControllers();
    }

      通过构造函数注入: 

    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        private readonly IVipService _vipService;
    
        public WeatherForecastController( IVipService vipService)  //在构造函数中注入IVipService接口
        {
            _vipService = vipService;
        }
    
        [HttpGet]
        public string Get( )
        {
            return _vipService.GetHashCode().ToString();
        }
    }

      通过方法注入:

    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
    
        [HttpGet]
        public string Get([FromServices]IVipService vipService)  // 在方法入参中使用[FromServices]特性注入IVipService接口
        {
            return vipService.GetHashCode().ToString();
        }
    }  

       这样我们就完成了一个依赖注入的简单示例,当有请求路由到WeatherForecastController控制器时,依赖注入框架会自动将Ioc容器中的实现类创建好注入到WeatherForecastController中,这样WeatherForecastController也就不在依赖于IVipService的具体实现类,如果需要更换IVipService的实现,那么只需要修改 services.AddScoped<IVipService, VipService>(); 这一段代码就可以了。

    生命周期  

       .net core的依赖注入框架支持创建三种不同生命周期的服务。

    public enum ServiceLifetime
    {
        // 单例模式
        Singleton = 0,
        // 作用域模式
        Scoped = 1,
        // 瞬时模式
        Transient = 2
    }
      Singleton :单例模式,在整个应用程序的生命周期内,每次调用都使用同一个实例。
      Scoped :作用域模式,在同一个作用域内,每次调用都使用同一个实例。
      Transient:瞬时模式,每次调用都会创建一个新的实例。
    三种生命周期,使用下面三种不同的方法注入
    services.AddSingleton<IVipService, VipService>();
    services.AddScoped<IVipService, VipService>();
    services.AddTransient<IVipService, VipService>();

       实现了IDisposable接口并且由容器创建的实例由容器主动释放,其他的实例生命周期结束后由GC释放。

    泛型模板注入

    services.AddSingleton(typeof(IVipService<>),typeof(VipService<>)); 

    工厂注入(用以处理一些特殊的情况)

    //一个接口 两个实现类 
    public interface IVipService
    {
    }
    
    public class ErpVipService : IVipService
    {
    }
    
    public class WxVipService : IVipService
    {
    }
    //将工厂包装一层
    public class VipServiceFactory
    {
        private readonly Func<int, IVipService> _func;
        public VipServiceFactory(Func<int, IVipService> func)
        {
            _func = func;
        }
        public IVipService GetInstence(int type)
        {
            return _func(type);
        }
    }
    //注入扩展类
    public static class VipServiceExtensions
    {
        public static IServiceCollection AddVipService(this IServiceCollection services)
        {
            services.AddScoped<ErpVipService>();
            services.AddScoped<WxVipService>();
            //通过工厂方式根据类型条件决定创建哪个实现类
            services.AddScoped(serviceProvider =>
            {
                Func<int, IVipService> func = type =>
                {
                    if (type == 0) return (IVipService)serviceProvider.GetService<ErpVipService>();
                    else
                        return (IVipService)serviceProvider.GetService<WxVipService>();
                };
                return func;
            });
            services.AddScoped<VipServiceFactory>();
            return services;
        }
    }

      在ConfigureServices中注入

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddVipService();
        services.AddControllers();
    }

      控制器中使用

    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        private readonly VipServiceFactory _vipServiceFactory;
        
        //将工厂类注入到构造函数
        public WeatherForecastController(VipServiceFactory vipServiceFactory)
        {
            _vipServiceFactory = vipServiceFactory;
        }
    
        [HttpGet]
        public string Get( )
        {
          return   _vipServiceFactory.GetInstence(0).GetHashCode().ToString();
        }
    }

    手写Ioc容器

      自己手撸的一个简单Ioc容器实现,只是用以了解Ioc的内部实现原理,不喜勿喷。

      地址:https://github.com/Jasonbourne723/eShop/blob/main/src/Tests/dotnet.Console.Test/Program.cs

    开源框架推荐

      Scrutor: Kristian Hellang 大神写的一个基于Microsoft.Extensions.DependencyInjection的一个扩展库,主要是为了简化我们对DI的操作。
      Autofac: .NET领域最为流行的IoC框架之一,功能多,性能好,易学习。 

     官方文档

      https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-3.1

  • 相关阅读:
    Java实现 蓝桥杯 历届试题 连号区间数
    Java实现 蓝桥杯 历届试题 连号区间数
    Java实现 蓝桥杯 历届试题 连号区间数
    Java实现 蓝桥杯 历届试题 连号区间数
    Java实现 蓝桥杯 历届试题 连号区间数
    Java实现 蓝桥杯 历届试题 大臣的旅费
    Java实现 蓝桥杯 历届试题 大臣的旅费
    Java实现 蓝桥杯 历届试题 大臣的旅费
    Java实现 蓝桥杯 历届试题 大臣的旅费
    Navicat查询哪些表有指定字段名
  • 原文地址:https://www.cnblogs.com/jasonbourne3/p/14611684.html
Copyright © 2011-2022 走看看