NET6 IOC 基本流程 泛型为例( 蒋金楠老师书籍)

 

1
2
3
4
5
6
7
8
9
10
11
using App;
using System.Diagnostics;
 
var cat = new Cat()
    .Register<IFoo, Foo>(Lifetime.Transient)
    .Register<IBar, Bar>(Lifetime.Transient)
    .Register(typeof(IFoobar<,>), typeof(Foobar<,>), Lifetime.Transient);
 
var foobar = (Foobar<IFoo, IBar>?)cat.GetService<IFoobar<IFoo, IBar>>();
Debug.Assert(foobar?.Foo is Foo);
Debug.Assert(foobar?.Bar is Bar);

1 初始化容器。

2将要注册的接口和对象准备好并开始注册。生命周期为Transient的在容器拓展方法注册一个委托

3 在添加到ServiceRegistry 里,检查容器是否释放,检查是否已注册,添加到一个线程安全的字典内,

ConcurrentDictionary<Type, ServiceRegistry> ,然后创建容器,就是new 这个容器并返回

4 获取服务,在容器拓展 GetService 方法,传入要获取的服务,检查容器是否释放,判断类型是否等于容器或者是IServiceProvider,判断是普通类型还是泛型,以泛型为例。serviceType.GetGenericTypeDefinitio获取泛型的实际基本类型(如T,T2,TKey,TValue等,看微软文档大概是这么个意思), ConcurrentDictionary 根据键获取值,没有则返回null。

5 new Key对象(此处key作用是在生命周期不是Transient时,用作为键添加服务进去),,并传入ServiceRegistry和刚刚方向的参数, 根据生命周期选择不同的创建方式(就是在创建前做些检查),然后调用前面存入ServiceRegistry 的委托准备创建对象。检查是否泛型,是否有构造函数等,(普通对象最后创建 Activator.CreateInstance(type);对象,(微软源码因该是用表达式树创建的对象)).而泛型则要先根据泛型参数,MakeGenericType生成类型,然后遍历在容第四步执行最后在Activator.CreateInstance(type),创建完成后添加到ConcurrentBag<IDisposable> 一个线程安全的适合多线程的集合,以便进行释放,然后有执行一个委托,最后来到接口的实现类,并且构造函数注入了对象。

 

其他:当生命周期为 单例或者容器内的单例时,先要检查当前类型是否存在,存在直接返回,不存在则去创建,然后添加到 ConcurrentDictionary<Key, object?> _services 里面,添加到ConcurrentBag<IDisposable> 一个线程安全的适合多线程的集合并返回

 

posted @   孤海飞雁  阅读(81)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
点击右上角即可分享
微信分享提示