博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ASP.NET Core 2.2 基础知识(一) 依赖注入
阅读量:5243 次
发布时间:2019-06-14

本文共 4602 字,大约阅读时间需要 15 分钟。

原文:

依赖:

类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
dic; public IoCContainer() { Init(); } private void Init() { dic = new Dictionary
{ {
typeof(IDepenency),new MyDependency() } }; } public T GetInstance
() { return (T)dic[typeof(T)]; } }

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

internal class Program    {        private static void Main(string[] args)        {            IoCContainer container = new IoCContainer();//创建一个容器            IDepenency dependency = container.GetInstance
();//获取注册的实例 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
(); }

 

使用:

[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
(); services.AddScoped
(); services.AddSingleton
(); //通过代码将实例添加到容器中. services.AddSingleton
(new Operation(Guid.Empty)); //OperationService 只能注册临时和作用域生存期 services.AddTransient
();

 

posted on
2019-01-04 00:35 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/lonelyxmas/p/10217728.html

你可能感兴趣的文章
【译】在Asp.Net中操作PDF - iTextSharp - 使用字体
查看>>
.net 文本框只允许输入XX,(正则表达式)
查看>>
实验2-2
查看>>
MongoDB遇到的疑似数据丢失的问题。不要用InsertMany!
查看>>
android smack MultiUserChat.getHostedRooms( NullPointerException)
查看>>
[置顶] Linux终端中使用上一命令减少键盘输入
查看>>
BootScrap
查看>>
Java实现二分查找
查看>>
UIImage 和 iOS 图片压缩UIImage / UIImageVIew
查看>>
php7 新特性整理
查看>>
RabbitMQ、Redis、Memcache、SQLAlchemy
查看>>
03 线程池
查看>>
手机验证码执行流程
查看>>
设计模式课程 设计模式精讲 2-2 UML类图讲解
查看>>
Silverlight 的菜单控件。(不是 Toolkit的)
查看>>
jquery的contains方法
查看>>
linux后台运行和关闭SSH运行,查看后台任务
查看>>
桥接模式-Bridge(Java实现)
查看>>
303. Range Sum Query - Immutable
查看>>
【★】浅谈计算机与随机数
查看>>