C#实现乞丐版IOC容器

一、前言

netcore中的容器非常好用,今天我们自己来简单实现一个。

实现容器的核心接口有两个:IServiceCollection、IServiceProvider。其中IServiceCollection定义容器集合,IServiceProvider提供容器中对象的访问。话不多说,直接编码。

二、IServiceCollection

首先我们得定义IServiceCollection接口,这个接口主要用以帮我们实现自定义集合,所以我们选择继承IList。代码如下:

细心你肯定发现了IList中ServiceDescriptor的定义了,这个类其实就是一个服务的描述类,我们F12进去看一下是怎么定义的。代码如下:

真的就是非常简单,ServiceType和ImplServiceType分别定义接口和实现类,LifeTime是一个枚举,用来定义这个类型的生命周期。代码如下:

现在我们已经定义好了IServiceCollection,下面就定义它的实现类:ServiceCollection,这个类就是具体的维护一个ServiceDescriptor集合。代码如下:

你也看到了,这个类,真的太简单了,就是用来将服务添加到集合_descriptors中了。唉,简单到不想多说了。写到这里,乞丐版容器其实已经实现了,我们来弄个控制台试下。代码如下:

细心的你可能会问,工作中使用容器的时候好像都是用的AddSingleton、AddScope的方法注入的,其实这些都是对IServiceCollection的扩展方法。那我们也来弄一个吧,先定义一个扩展类:ServiceCollectionExtensions。代码如下:

写好这些扩展方法后,我们再来改下控制台中的代码,就和你实际工作中长一样了。代码如下:

三、IServiceProvider

这时你可能又会问,服务我已经注册到容器了,我要怎么使用呢?这个时候我们就要用到开头所说的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容器就完成了,能力有限,只是实现最简单的功能,很多校验都没有写。还是建议大家直接看微软的源码,那个里面写的比较高端,我这只是毛毛雨,如果能帮到你一点点,我就会很开心了,哈哈。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值