.NET的依赖注入框架Microsoft.Extensions.DependencyInjection,支持注入未绑定的泛型类(Unbound generic type)
C#的关键字typeof可以用来获取未绑定的泛型类/接口(Unbound generic type)的Type类实例,未绑定的泛型类/接口(Unbound generic type)就是指没有指定类型参数的泛型类/接口,如下代码所示:
using System; namespace NET5UnboundGenericDependencyInjectionDemos { /// <summary> /// 泛型类Container<T> /// </summary> /// <typeparam name="T">泛型类型参数</typeparam> class Container<T> { } class Program { static void Main(string[] args) { Type unboundGenericType = typeof(Container<>);//通过typeof关键字,获取未绑定的泛型类Container<T>的Type类实例 Console.WriteLine(unboundGenericType.ToString()); Console.WriteLine("Press any key to end..."); Console.ReadKey(); } } }
运行上面代码,结果如下:
可以看到Type类实例unboundGenericType输出的信息中,泛型类Container<T>的类型参数T,并没有被指定为具体的类型,所以是未绑定的泛型类。
未绑定的泛型类常常被用于依赖注入中,这样可以大大增加代码的复用性,而微软的依赖注入框架Microsoft.Extensions.DependencyInjection支持注入未绑定的泛型类。
首先我们创建一个.NET 5.0控制台项目,然后引入nuget包:Microsoft.Extensions.DependencyInjection
项目的代码如下所示:
using Microsoft.Extensions.DependencyInjection; using System; namespace NET5UnboundGenericDependencyInjectionDemos { /// <summary> /// 泛型接口IContainer<T> /// </summary> /// <typeparam name="T">泛型类型参数,where T : new()约束保证类型T具有公共无参数构造函数</typeparam> interface IContainer<T> where T : new() { T Element { get; } /// <summary> /// 显示泛型类型参数T的Type类型 /// </summary> void ShowElementType(); } /// <summary> /// 泛型类Container<T>,实现接口IContainer<T> /// </summary> /// <typeparam name="T">泛型类型参数,where T : new()约束保证类型T具有公共无参数构造函数</typeparam> class Container<T> : IContainer<T> where T : new() { protected T element; public Container() { element = new T(); } public T Element { get { return element; } } /// <summary> /// 显示泛型类型参数T的Type类型 /// </summary> public void ShowElementType() { Console.WriteLine(element.GetType().ToString()); } } /// <summary> /// 类People,作为泛型接口IContainer<T>和泛型类Container<T>的类型参数T /// </summary> class People { public void Speak() { Console.WriteLine("I'm a people!"); } } class Program { static void Main(string[] args) { IServiceCollection serviceDescriptors = new ServiceCollection(); serviceDescriptors.AddTransient(typeof(IContainer<>), typeof(Container<>));//注册未绑定的泛型接口IContainer<T>和未绑定的泛型类Container<T>的依赖注入关系 IContainer<People> container = null;//声明关闭的泛型接口IContainer<People>变量container,下面使用依赖注入来为其赋值 using (ServiceProvider serviceProvider = serviceDescriptors.BuildServiceProvider()) { using (IServiceScope serviceScope = serviceProvider.CreateScope()) { container = serviceScope.ServiceProvider.GetService<IContainer<People>>();//使用依赖注入为泛型接口IContainer<People>变量container赋值,依赖注入框架Microsoft.Extensions.DependencyInjection会构造一个关闭的泛型类Container<People>实例,赋值给IContainer<People> container } } Console.WriteLine(container.GetType().ToString());//显示泛型接口IContainer<People>变量container的实际类型 container.ShowElementType();//调用泛型接口IContainer<People>的ShowElementType方法 container.Element.Speak();//调用泛型接口IContainer<People>的类型参数People的Speak方法 Console.WriteLine("Press any key to end..."); Console.ReadKey(); } } }
运行上面代码,结果如下:
我们可以看到,使用依赖注入框架Microsoft.Extensions.DependencyInjection,我们可以为关闭的泛型接口(Closed generic type)IContainer<People>,来注入关闭的泛型类(Closed generic type)Container<People>,关闭的泛型类/接口(Closed generic type)就是指指定了具体类型参数的泛型类/接口,上面代码中泛型的类型参数就是People类。
注意上面代码中,我们在注册依赖注入关系的时候(AddTransient),是注册的未绑定的泛型接口IContainer<T>和未绑定的泛型类Container<T>的依赖注入关系,但是依赖注入框架Microsoft.Extensions.DependencyInjection,还是可以为关闭的泛型接口IContainer<People>,获得关闭的泛型类Container<People>。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架