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

依赖:设计模式

类A用到了类B,咱们就说类A依赖类B.若是一个类没有任何地方使用到,那这个类基本上能够删掉了.api

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 类.函数

 

依赖倒置:ui

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

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

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

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

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

上层不该该依赖下层,Test 类不该该依赖 MyDependency 类,由于若是 MyDependency 类变化了,就是把这种变化所形成的影响传递到上层 Test 类.blog

所以,上例按照依赖倒置原则修改以下:

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>();
相关文章
相关标签/搜索