Asp.net core 学习笔记--(1)依赖注入

来源:互联网 发布:inux高性能服务器编程 编辑:程序博客网 时间:2024/06/03 11:15

依赖注入

依赖注入是一种软件的设计技巧,它主要解决的是类与类之间的耦合,这种设计技巧满足面向对象设计的”依赖倒置“原则:类与类之间不相互依赖,都要依赖接口。比如说controller中需要一个”AccessDataBase“的类型来进行对数据库的检索,那么我们可以将这个AccessDataBase类中实现的功能做成一个接口,然后让这个类去实现这个接口,然后,我们在需要这个类的地方(本例中是controller)给他塞进去一个接口,然后通过DI容器去提供具体的实现。DI容器就是这个一个东西。
asp.net core 内置了依赖注入,主要是通过Microsoft.Extensions.DependencyInjection的nuget包来实现的。
DI容器就是一个由IServiceProvider的接口来实现的:

 public interface IServiceProvider    {        object GetService(Type serviceType);    }

这个接口看起来很简洁,其实我们用到的主要是这个接口的一些扩展方法
一个IServiceProvider要通过IServiceCollection这个接口来生成,这个接口在asp.net core中有具体实现,就是一个ServiceCollection。
如果要生成一个IServiceProvider,可以通过下面的代码来实现:

IServiceProvider service=new ServiceCollection().BuildServiceProvider();

这个是最简单的一种实现,因为在这个实现的过程中根本没有注册任何内容。

生命周期

DI容器除了提供接口的具体实现,还要去管理这个具体实现的生命周期。由DI容器生成的类就叫做”提供的服务“。提供的类是”服务“。
IServiceProvider就是asp.net core中的DI容器,它提供的服务是以三种不同形式的生命周期来实现的,这三种生命周期被放到一个枚举中:

 public enum ServiceLifetime    {        //        // 摘要:        //     Specifies that a single instance of the service will be created.        Singleton = 0,        //        // 摘要:        //     Specifies that a new instance of the service will be created for each scope.        //        // 备注:        //     In ASP.NET Core applications a scope is created around each server request.        Scoped = 1,        //        // 摘要:        //     Specifies that a new instance of the service will be created every time it is        //     requested.        Transient = 2    }

Singleton :单例类,应用程序中所有的地方只会出现一个,这个类的实例会被DI容器重复提供直到应用程序终止。
Transient:这个和singleton正好相反。只要调用它的地方就会被DI容器生成一个新的实例(服务)。
Scoped :这个是在每一个DI容器中是唯一的,意思就是说如果应用程序中产生了多个DI容器,那么针对每个DI容器的请求都会生成一个唯一的Scoped的服务。
而提到IServiceProvider就不得不说IServiceScope,具体IServiceProvider提供的服务的生命周期是由IServiceScope来决定的,而IServiceScope是由IServiceScopeFactory来提供的。
刚才说了IServiceProvider可以由一个ServiceCollection来实现,还有一种方法是由IServiceProvider配合IServiceScope来实现:

 static void Main(string[] args)        {  IServiceProvider root=new ServiceCollection().BuildServiceProvider();  IServiceProvider child = root.GetService<IServiceScopeFactory>().CreateScope().ServiceProvider;        }

关键是我们先要产生一个serviceprovider,然后用这个serviceprovider来产生另一个,这样,就形成了一种貌似”父子关系“:例如上面代码中的root和child。最终,我们会利用这个关系来阐述最后一个问题:serviceprovider对于其所提供的类的生命周期的管理:
singleton:这中生命周期类型的服务的生命周期会被”父亲“来进行管理。其他两种生命周期类型的服务会在各自生成的serviceprovider中进行管理。需要注意的是服务的终止是在IServiceProvider调用Dispose方法的时候自动进行的。但是这种做法也是有缺点的,那就是服务类不会得到及时的回收,一种更好的做法是通过IServiceScope:

using(IServiceScope scope=IServiceProvider.GetService<IServiceScopeFactory>().CreateScope()){IServiceProvider service=Scope.ServiceProvider;。。。。。。}

以上是伪代码。

在这片文章中IServiceProvider和DI容器和ServiceProvider是一个意思。特此说明。
这篇文章会随着我对asp.net core的理解逐步加入更多的东西,目的就是为了做好这个笔记以供后期复习。