我的编程空间,编程开发者的网络收藏夹
学习永远不晚

ASP.NET Core依赖注入(DI)讲解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

ASP.NET Core依赖注入(DI)讲解

ASP.NET Core的底层设计支持和使用依赖注入。ASP.NET Core 应用程序可以利用内置的框架服务将服务注入到启动类的方法中,并且应用程序服务也可以配置注入。由ASP.NET Core 提供的默认服务容器提供了最小功能集,并不是取代其他容器。

1.浅谈依赖注入

依赖注入(Dependency injection,DI)是一种实现对象和依赖者之间松耦合的技术,将类用来执行其操作的这些对象以注入的方式提供给该类,而不是直接实例化依赖项或者使用静态引用。一般情况,类会通过构造函数声明器2依赖关系,允许他们遵循显示依赖原则。这种方法称为“构造函数注入”。

当类的设计使用DI思想时,他们的耦合更加松散,因为他们没有对他们的合作者直接硬编码的依赖。这遵循“依赖倒置原则”,其中指出,高层模块不应该依赖于底层模块:两者都依赖于抽象。

类要求在他们构造时向其提供抽象(通常是接口),而不是引用特定的实现。提取接口的依赖关系和提供接口的实现作为参数也是“策略设计模式”的一个示例。

当一个类被用来创建类及其相关的依赖关系时,这个成为容器(containers),或者称为控制反转(Inversion of Control, IoC)容器,或者依赖注入容器。容器本质上是一个工厂,负责提供向它请求的类型的实例。如果一个给定类型声明它具有依赖关系,并且容器已经被配置为其提供依赖关系,那么它将把创建依赖关系作为创建请求实例的一部分。除了创建对象的依赖关系外,容器通常还会管理应用程序中对象的生命周期。

ASP.NET Core 包含一个默认支持构造函数注入的简单内置容器,ASP.NET 的容器指的是它管理的类型services,可以在Startup类的ConfigureServices方法中配置内置容器的服务。

2. 使用ASP.NET Core提供的服务

Startup类的ConfigureServices方法负责定义应用程序将使用的服务,包括平台自带的功能,比如,Entity Framework Core 和 ASP.NET Core MVC。除了IServiceCollection提供的几个服务之外,可以使用一些扩展方法(AddDbContext,AddMvc,AddTransient等)向容器添加和注册额外服务:

public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });


            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            services.AddDbContext<AccessManagementContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
                providerOptions => providerOptions.EnableRetryOnFailure()));
            services.AddTransient<ICompanyServices, CompanyServices>();

        }

ASP.NET Core 提供的功能和中间件,遵循约定使用一个单一的AddService扩展方法来注册所有该功能所需的服务。

3.注册自己的服务

我们可以按照 services.AddTransient<ICompanyServices, CompanyServices>(); 这种写法注册自己的服务。第一个范型类型表示将要从容器中请求的类型(通常是一个接口)。第二个范型类型表示将由容器实例化并且用于完成请求的具体类型。

AddTransient 方法用于将抽象类型映射到为每一个需要它的对象分别实例化的具体服务。为注册的每一个服务选择合适的生命周期很重要,后面会介绍到。

下面是示例是注册自己的服务:

1.接口

public interface IAccountServices
    {
        Task<List<AccountViewModel>> GetList();
    }

2.实现类

public class AccountServices:IAccountServices
    {
        AccessManagementContext _context;
        public AccountServices(AccessManagementContext context)
        {
            _context = context;//在构造函数中注入
        }

        public async Task<List<Account>> GetList()
        {
            try
            {
                var query = _context.Account.ToListAsync();
                 return query ;
            }
            catch (Exception ex)
            {
                return null;
            }

        }
}

3.在ConfigureServices中注册自定义的服务和EF上下文AccessManagementContext 

public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            services.AddDbContext<AccessManagementContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
                providerOptions => providerOptions.EnableRetryOnFailure()));
            services.AddTransient<IAccountServices,AccountServices>();

        }

4.在Controller构造函数中依赖注入

public class AccountController : Controller
    {
        private IAccountServices _accountServices;
        public AccountController(IAccountServices accountServices)
        {
            _accountServices = accountServices;
        }
        // GET: Account
        public async Task<ActionResult> Index()
        {
            var vms = await _accountServices.GetList();
            return View(vms);
        }

4.服务的生命周期和注册选项

ASP.NET 服务生命周期:

  • 1.Transient 瞬时
    Transient 生命周期服务在他们每次请求时被创建。适合轻量级,无状态的服务。
  • 2.Scoped 作用域
    Scoped生命周期在每次请求时创建一次。
  • 3.Singleton 单例
    Singleton 生命周期服务在它们第一次请求时创建,并且每个后续请求使用相同的实例。

服务可以用多种方式在容器中注册,除了之前的注册方法,还可以指定一个工厂,它将被用来创建需要的实例。后面会详细介绍其他的注册方法。

下面用一个简单的示例介绍每个生命周期:

1.创建接口:

namespace MVCTest.Interfaces
{
    public interface IOperation
    {
        /// <summary>
        /// 唯一标识
        /// </summary>
        Guid OperationId { get;  }
    }

    public interface IOperationTransient: IOperation
    {
    }

    public interface IOperationScoped : IOperation
    {
    }

    public interface IOperationSingleton : IOperation
    {
    }

    public interface IOperationInstance : IOperation
    {
    }
}

2.实现类

/// <summary>
    /// 实现所有接口
    /// </summary>
    public class Operation: IOperation, IOperationTransient,
        IOperationScoped, IOperationSingleton, IOperationInstance
    {
        public Operation()
        {
            OperationId = Guid.NewGuid();
        }
        public Operation(Guid operationId)
        {
            if (operationId == null)
            {
                OperationId = Guid.NewGuid();
            }
            OperationId = operationId;
        }

        public Guid OperationId { get; }
    }

3.注册到容器

public void ConfigureServices(IServiceCollection services)
        {
            services.AddTransient<IOperationTransient, Operation>();
            services.AddScoped<IOperationScoped, Operation>();
            services.AddSingleton<IOperationSingleton, Operation>();
            services.AddSingleton<IOperationInstance, Operation>();
            services.AddTransient<OperationServices, OperationServices>();
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }

4.上面还注册了 OperationServices ,用来测试单例模式(单例生命周期服务中所有请求使用第一次实例化的服务)和 作用域生命周期服务在每次请求时只创建一次,不管几个地方用到实例

public class OperationServices
    {
        public IOperationTransient OperationTransient { get;  }
        public IOperationScoped OperationScoped { get;  }
        public IOperationSingleton OperationSingleton { get;  }
        public IOperationInstance OperationInstance { get;  }

        public OperationServices(IOperationTransient operationTransient,
            IOperationScoped operationScoped,
            IOperationSingleton operationSingleton,
            IOperationInstance operationInstance)
        {
            OperationTransient = operationTransient;
            OperationScoped = operationScoped;
            OperationSingleton = operationSingleton;
            OperationInstance = operationInstance;
        }
    }

5.在Controller中使用

public class OperationController : Controller
    {
        public IOperationTransient OperationTransient { get; }
        public IOperationScoped OperationScoped { get; }
        public IOperationSingleton OperationSingleton { get; }
        public IOperationInstance OperationInstance { get; }
        public OperationServices _operationServices;

        public OperationController(IOperationTransient operationTransient,
            IOperationScoped operationScoped,
            IOperationSingleton operationSingleton,
            IOperationInstance operationInstance,
            OperationServices operationServices)
        {
            OperationTransient = operationTransient;
            OperationScoped = operationScoped;
            OperationSingleton = operationSingleton;
            OperationInstance = operationInstance;
            _operationServices = operationServices;
        }
        // GET: Operation
        public ActionResult Index()
        {
            ViewBag.OperationTransient = OperationTransient;
            ViewBag.OperationScoped = OperationScoped;
            ViewBag.OperationSingleton = OperationSingleton;
            ViewBag.OperationInstance = OperationInstance;
            ViewBag._operationServices = _operationServices;
            return View();
        }
}

6.Index显示

@{
    ViewData["Title"] = "Index";
}

<div>
    <h1>Controller Operations</h1>
    <h2>OperationTransient: @ViewBag.OperationTransient.OperationId</h2>
    <h2>OperationScoped: @ViewBag.OperationScoped.OperationId</h2>
    <h2>OperationSingleton: @ViewBag.OperationSingleton.OperationId</h2>
    <h2>OperationInstance: @ViewBag.OperationInstance.OperationId</h2>
</div>
<div>
    <h1>Services Operations</h1>
    <h2>OperationTransient: @ViewBag._operationServices.OperationTransient.OperationId</h2>
    <h2>OperationScoped: @ViewBag._operationServices.OperationScoped.OperationId</h2>
    <h2>OperationSingleton: @ViewBag._operationServices.OperationSingleton.OperationId</h2>
    <h2>OperationInstance: @ViewBag._operationServices.OperationInstance.OperationId</h2>
</div>

7.运行结果

可以看到,单例生命周期服务每一次请求的标识一样。作用域生命周期的服务,在一次请求中使用的同一个实例,第二次请求创建新的实例。

5.请求服务

来自HttpContext的一次ASP.NET 请求中,可用的服务是通过RequestServices集合公开的。

请求服务将你配置的服务和请求描述为应用程序的一部分。在子的对象指定依赖之后,这些满足要求的对象可通过查找RequestServices中对应的类型得到,而不是ApplicationServices。

6.设计依赖注入服务

在自定义的服务中,避免使用静态方法和直接实例化依赖的类型,而是通过依赖注入请求它。(New is Glue)

如果类有太多的依赖关系被注入时,通常表明你的类试图做的太多(违反了单一职责原则),需要转移一些职责。

同样,Controller类应该重点关注UI,因此业务逻辑和数据访问等细节应该在其他类中。

7.使用Autofac容器

Autofac

到此这篇关于ASP.NET Core依赖注入(DI)的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持编程网。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

ASP.NET Core依赖注入(DI)讲解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

ASP.NET Core依赖注入DI容器怎么实现

这篇文章主要介绍“ASP.NET Core依赖注入DI容器怎么实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“ASP.NET Core依赖注入DI容器怎么实现”文章能帮助大家解决问题。ASP.NE
2023-07-05

详解asp.net core 依赖注入

前言好久没有写微博了,因为前段时间由于家庭原因决定从工作了3年多的北京转移到上海去。依赖注入在学习net core的时候也有写过类似的东西,只是实践的较少,结果来到上海新公司系统框架涉及到了这块知识点,所以在了解完自己的项目之后决定做一些相
2022-06-07

ASP.NET Core依赖注入DI容器的方法实现

本文介绍了ASP.NETCore中依赖注入(DI)容器的实现方法。DI容器管理对象生命周期和依赖关系,使应用程序更加模块化、可测试和可维护。注册服务的方式包括Transient、Scoped和Singleton,解析依赖项的方式包括构造函数注入、属性注入和方法注入。DI容器负责管理对象生命周期,可以选择内置容器或第三方容器。遵循最佳实践,如使用最小作用域、构造函数注入和测试依赖项解析,以充分利用DI容器。
ASP.NET Core依赖注入DI容器的方法实现
2024-04-02

ASP.NET Core依赖注入实例分析

今天小编给大家分享一下ASP.NET Core依赖注入实例分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。ASP.NET
2023-06-30

Spring DI依赖注入过程解析

依赖注入是由“依赖”和“注入”两个词汇组合而成,那么我们再一次顺藤摸瓜,分别分析这两个词语,这篇文章主要介绍了Spring DI依赖注入详解,需要的朋友可以参考下
2022-11-13

ASP.NET Core依赖关系注入怎么实现

本篇内容主要讲解“ASP.NET Core依赖关系注入怎么实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“ASP.NET Core依赖关系注入怎么实现”吧!1.前言面向对象设计(OOD)里有一
2023-06-29

ASP.NET Core 依赖注入生命周期示例详解

ASP.NETCore依赖注入生命周期示例详解。生命周期控制对象创建和销毁,防止内存泄漏。不同生命周期包括:瞬态服务:每次请求创建新实例,适用于轻量级、无状态服务。作用域服务:请求处理期间创建一次实例,适用于需要跨请求保持状态的服务。单例服务:应用程序生命周期中创建一次实例,适用于全局需要服务。可通过构造函数注入依赖项,并根据具体情况选择不同生命周期,以优化应用程序性能。
ASP.NET Core 依赖注入生命周期示例详解
2024-04-02

ASP.NET Core依赖注入生命周期是什么

这篇文章主要介绍“ASP.NET Core依赖注入生命周期是什么”,在日常操作中,相信很多人在ASP.NET Core依赖注入生命周期是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”ASP.NET Cor
2023-07-05

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录