ASP.NET Core 2.2 基础知识(一) 依赖注入

原文:ASP.NET Core 2.2 基础知识(一) 依赖注入

依赖:

类A用到了类B,我们就说类A依赖类B.如果一个类没有任何地方使用到,那这个类基本上可以删掉了.

    public class Test
    {
        private MyDependency md = new MyDependency();

        public void Print()
        {
            md.Print();
        }
    }
    public class MyDependency
    {
        public void Print()
        {
            Console.WriteLine("this is mydependency");
        }
    }

上面的示例中,Test 类就依赖 MyDependency 类.

依赖倒置:

依赖倒置原则是五大原则之一:

1.上层模块不应该依赖于下层模块,它们共同依赖于一个抽象.

2.抽象不能依赖于具象,具象依赖于抽象.

什么是上层?使用者就是上层,上例中,Test 类就是上层.

什么是下层?被使用者就是下层.上例中,Test 类使用了 MyDependency 类, MyDependency 类就是下层.

上层不应该依赖下层,Test 类不应该依赖 MyDependency 类,因为如果 MyDependency 类变化了,就是把这种变化所造成的影响传递到上层 Test 类.

因此,上例按照依赖倒置原则修改如下:

    public class Test
    {
        private IDepenency md = new MyDependency();

        public void Print()
        {
            md.Print();
        }
    }
    public interface IDepenency
    {
        void Print();
    }

    public class MyDependency : IDepenency
    {
        public void Print()
        {
            Console.WriteLine("this is mydependency");
        }
    }

控制反转(IoC):Inversion of Control

控制反转是一种思想,所谓"控制反转",就是反转获得依赖对象的过程.或许,叫"反转控制"更容易理解.

上例虽然遵循了"依赖倒置原则",但是违背"开放封闭原则",因为如果有一天想修改 md 为 YourDependency 类的实例,则需要修改 Test 类.因此,我们需要反转这种创建对象的过程.

    internal class Program
    {
        private static void Main(string[] args)
        {
            Test test = new Test(new MyDependency());
            test.Print();
            Console.ReadKey();
        }
    }

    public class Test
    {
        private IDepenency md;

        public Test(IDepenency depenency)
        {
            md = depenency;
        }

        public void Print()
        {
            md.Print();
        }
    }

上例中,将 md 的创建过程"反转"给了调用者.

依赖注入(DI):Dependency Inject

依赖注入设计模式是一种在类及其依赖对象之间实现控制反转(IOC)思想的技术.

所谓依赖注入,就是由IoC容器在运行期间,动态地将某种依赖关系注入到对象之中。

我们先创建一个简易的IoC容器(当然,实际的 IoC 容器复杂得多.):

    public class IoCContainer
    {
        private Dictionary<Type, Object> dic;

        public IoCContainer()
        {
            Init();
        }

        private void Init()
        {
            dic = new Dictionary<Type, object>
            {
                {typeof(IDepenency),new MyDependency() }
            };
        }

        public T GetInstance<T>()
        {
            return (T)dic[typeof(T)];
        }
    }

那么,上例的调用,则可以修改成:

    internal class Program
    {
        private static void Main(string[] args)
        {
            IoCContainer container = new IoCContainer();//创建一个容器
            IDepenency dependency = container.GetInstance<IDepenency>();//获取注册的实例
            Test test = new Test(dependency);
            test.Print();
            Console.ReadKey();
        }
    }

依赖注入分为3中:构造函数注入,属性注入,方法注入,上例属于构造函数注入.

ASP.NET Core 中的依赖注入

ASP.NET Core 内置的IoC容器,只支持构造函数注入,注入的方式如下:

在 Startup 类的 ConfigureServices 方法中注册.

        public void ConfigureServices(IServiceCollection services)
        {                    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

            //DI
            services.AddTransient<IDependency, MyDependency>();
        }

使用:

    [Route("api/[controller]")]
    [ApiController]
    public class ValuesController : ControllerBase
    {
        private readonly IDepenency _dependency;
        public ValuesController(IDepenency dependency)
        {
            _dependency = dependency;
        }

        ...other codes  }

生存期

这是依赖注入设计原则里一个非常重要的概念,ASP.NET Core 一共有3种生存期:

1.暂时(Transient) : services.AddTransient<IDependency, MyDependency>(); 顾名思义,这种生存期的对象是暂时的,每次请求都会创建一个新的实例.

2.作用域(Scoped) : services.AddScoped<IDepenency, MyDependency>(); 每次请求使用的是同一个实例.

3.单例(Singleton) : services.AddSingleton<IDepenency, MyDependency>(); 第一次请求时就创建,以后每次请求都是使用的相同的实例.

这种生存期的对象还有一种注册方式:  services.AddSingleton<IDepenency>(new MyDependency());

这种方式与其他所有方式的区别在于:如果 MyDependency 实现了  IDisposable ,那么其他方式注册的实例,容器会自动释放,也就是说,容器创建的实例会自动释放,但这种方式不会,因为这种方式注册的实例不是容器创建的.

官方文档建议:

依赖注入是静态/全局对象访问模式的替代方法.如果将其与静态对象访问混合使用,则可能无法实现依赖关系注入的优点。

ps 还没搞明白的问题:

OperationService 依赖  IOperationTransient,IOperationScoped,IOperationSingleton,IOperationSingletonInstance,但是它只能注册 暂时和作用域 生存期,不能注册单例生存期

                services.AddTransient<IOperationTransient, Operation>();
                services.AddScoped<IOperationScoped, Operation>();
                services.AddSingleton<IOperationSingleton, Operation>();
                //通过代码将实例添加到容器中.
                services.AddSingleton<IOperationSingletonInstance>(new Operation(Guid.Empty));
                //OperationService 只能注册临时和作用域生存期
                services.AddTransient<OperationService, OperationService>();

原文地址:https://www.cnblogs.com/lonelyxmas/p/10217728.html

时间: 2024-08-11 01:35:53

ASP.NET Core 2.2 基础知识(一) 依赖注入的相关文章

ASP.NET Core 2.2 基础知识(二) 中间件

原文:ASP.NET Core 2.2 基础知识(二) 中间件 中间件是一种装配到应用管道以处理请求和相应的软件.每个软件都可以: 1.选择是否将请求传递到管道中的下一个组件; 2.可在调用管道中的下一个组件前后执行工作. 管道由 IApplicationBuilder 创建: 每个委托都可以在下一个委托前后执行操作,.此外,委托还可以决定不将请求传递给下一个委托,这就是对请求管道进行短路.通常需要短路,是因为这样可以避免不必要的工作.比如: 1.静态文件中间件可以返回静态文件请求并使管道的其余

ASP.NET Core 2.2 基础知识(十一) ASP.NET Core 模块

原文:ASP.NET Core 2.2 基础知识(十一) ASP.NET Core 模块 ASP.NET Core 应用与进程内的 HTTP 服务器实现一起运行.该服务器实现侦听 HTTP 请求,并在一系列请求功能被写到 HttpContext 时,将这些请求展现到应用中. ASP.NET Core 随附两种服务器实现: Kestrel 是适用于 ASP.NET Core 的默认跨平台 HTTP 服务器. HTTP.sys 是仅适用于 Windows 的 HTTP 服务器,它基于 HTTP.sy

ASP.NET Core 2.2 基础知识(六) 配置(内含MySql+EF)

原文:ASP.NET Core 2.2 基础知识(六) 配置(内含MySql+EF) 先上一段代码,了解一下 .NET Core 配置数据的结构. 新建一个 控制台项目,添加一个文件 json.json ,文件内容如下: { "country": "cn", "person": { "id": 1, "address": { "addName": "chengdu"

ASP.NET Core 2.2 基础知识(五) 环境

原文:ASP.NET Core 2.2 基础知识(五) 环境 一.环境变量 系统启动时,会读取环境变量 ASPNETCORE_ENVIRONMENT ,并将该变量的值存储在 IHostingEnvironment.EnvironmentName 字段中.如: 新建一个 WebAPI 项目,修改 Configure 方法: public void Configure(IApplicationBuilder app, IHostingEnvironment env) { ...... { app.R

ASP.NET Core 2.2 基础知识(十六) SignalR 概述

原文:ASP.NET Core 2.2 基础知识(十六) SignalR 概述 我一直觉得学习的最好方法就是先让程序能够正常运行,才去学习他的原理,剖析他的细节. 就好像这个图: 所以,我们先跟着官方文档,创建一个 SignalR 应用: https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/signalr?view=aspnetcore-2.2&tabs=visual-studio 这个例子一共涉及到下面几个步骤: 自定义中心 ChatH

ASP.NET Core 2.2 基础知识(十二) 发送 HTTP 请求

可以注册 IHttpClientFactory 并将其用于配置和创建应用中的 HttpClient 实例. 这能带来以下好处: 提供一个中心位置,用于命名和配置逻辑 HttpClient 实例. 例如,可以注册 github 客户端,并将它配置为访问 GitHub. 可以注册一个默认客户端用于其他用途. 通过委托 HttpClient 中的处理程序整理出站中间件的概念,并提供适用于基于 Polly 的中间件的扩展来利用概念. 管理基础 HttpClientMessageHandler 实例的池和

ASP.NET Core 2.2 基础知识(十八) 托管和部署 概述

为了方便演示,以 .NET Core 控制台应用程序讲解. 我们新建一个控制台应用程序,安装 "Newtonsoft.Json" Nuget 包,然后右键点击该项目,选择"发布": 我们依次选择"文件",设置好路径,最后点击创建配置文件,界面变成了下面这样: 然后我们点击"配置" 那么,问题来了."部署模式" 里面有两个选项: 1.当选择框架依赖时,"目标运行时"有:"可移植&

ASP.NET Core 基础知识(一) 依赖注入

依赖: 类A用到了类B,我们就说类A依赖类B.如果一个类没有任何地方使用到,那这个类基本上可以删掉了. public class Test { private MyDependency md = new MyDependency(); public void Print() { md.Print(); } } public class MyDependency { public void Print() { Console.WriteLine("this is mydependency"

ASP.NET Core 2.2 基础知识(四) URL重写中间件

说到URL重写就不得不提URL重定向. URL重定向 URL重定向是客户端操作,指示客户端访问另一个地址的资源.这需要往返服务器,并且当客户端对资源发出请求时,返回客户端的重定向URL会出现在浏览器的地址栏中. 将请求重定向到不同的URL时,可指示重定向是永久的还是临时的.如果是永久的,则使用"301"状态码.收到"301"状态码时,客户端可能会缓存.如果是临时的,则使用"302"状态码,以使客户端将来不应存储和重用重定向URL. 示例: 新建一