C#实现乞丐版IOC容器
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#实现乞丐版IOC容器相关的知识,希望对你有一定的参考价值。
netcore中的容器非常好用,今天我们自己来简单实现一个。
实现容器的核心接口有两个:IServiceCollection、IServiceProvider。其中IServiceCollection定义容器集合,IServiceProvider提供容器中对象的访问。话不多说,直接编码。
首先我们得定义IServiceCollection接口,这个接口主要用以帮我们实现自定义集合,所以我们选择继承IList。代码如下:
细心你肯定发现了IList中ServiceDescriptor的定义了,这个类其实就是一个服务的描述类,我们F12进去看一下是怎么定义的。代码如下:
真的就是非常简单,ServiceType和ImplServiceType分别定义接口和实现类,LifeTime是一个枚举,用来定义这个类型的生命周期。代码如下:
现在我们已经定义好了IServiceCollection,下面就定义它的实现类:ServiceCollection,这个类就是具体的维护一个ServiceDescriptor集合。代码如下:
你也看到了,这个类,真的太简单了,就是用来将服务添加到集合_descriptors中了。唉,简单到不想多说了。写到这里,乞丐版容器其实已经实现了,我们来弄个控制台试下。代码如下:
细心的你可能会问,工作中使用容器的时候好像都是用的AddSingleton、AddScope的方法注入的,其实这些都是对IServiceCollection的扩展方法。那我们也来弄一个吧,先定义一个扩展类:ServiceCollectionExtensions。代码如下:
写好这些扩展方法后,我们再来改下控制台中的代码,就和你实际工作中长一样了。代码如下:
这时你可能又会问,服务我已经注册到容器了,我要怎么使用呢?这个时候我们就要用到开头所说的IServiceProvider,这个接口定义访问容器中的服务,记住继承下IDispose,用来释放资源。代码如下:
定义好接口以后,我们就要弄一个实现类,即ServiceProvider,这个类中主要实现GetService方法,用来提供服务对象实例。代码如下:
ServiceProvider构造方法需要IServiceCollection对象,不然它都不知道提供哪个容器的服务对象。这个类中维护了一个_objects字典,用来管理单例(Singleton)、范围(Scoped)对象。GetService方法也非常的简单,先到容器对象中找下已注册的服务,如果找不到,直接返回null。如果找到,则根据这个注册类型的生命周期返回对象:瞬时对象的话每次都创建新对象,单例和范围对象的话先到_objects查询,如果有的话直接返回,没有的话重新创建一个,放回_objects后再返回。有了ServiceProvider类后,我们就可以在控制台中提供注册的服务对象了。代码如下:
上面的代码中,我们new了一个ServiceProvider对象,并把ServiceCollection对象传给了它,意思是我把容器交给你,访问服务对象的事就拜托你了。然后我们通过GetService得到几个单例和瞬时对象,我们运行下看下,他们hashcode是不是和我们预期的一样。代码如下:
我们发现得到的单例对象hashcode值都一样,瞬时对象每次都不一样,说明我们这个IOC基本功能已经实现了,真了不起。上面的new ServiceProvider我们也可以改成扩展方法。代码如下:
细心的你肯定又发现不对,你这一直没讲Scope呀。其实Scope和Singleton是一样的,Scope只是一定范围的单例。你只要在范围内每次new一个ServiceProvider就行了。代码如下:
至此,我们乞丐版的IOC容器就完成了,能力有限,只是实现最简单的功能,很多校验都没有写。还是建议大家直接看微软的源码,那个里面写的比较高端,我这只是毛毛雨,如果能帮到你一点点,我就会很开心了,哈哈。
以上是关于C#实现乞丐版IOC容器的主要内容,如果未能解决你的问题,请参考以下文章
C# WPF通过反射及Ioc容器综合实例
C# WPF通过反射及Ioc容器加载并显示其它项目界面(精品)
Java中如何实现一个IOC容器(个人理解&&简介版)
spring学习总结002 --- IOC容器启动源码(简易版)
spring IoC容器的实现。
IoC容器的实现( IoC 容器概述和在 Spring 中的应用场景)