Microsoft.Extensions.DependencyInjection在构造方法注入中,可以注入IServiceProvider接口实例
我们在使用Microsoft.Extensions.DependencyInjection进行构造方法依赖注入时,可以注入IServiceProvider接口的实例,然后可以用这个实例来获取其它依赖注入的类。
下面的示例代码中,我们定义了IPeople接口和实现类People,是一组依赖注入关系。还定义了IPeopleService接口和实现类PeopleService,也是一组依赖注入关系,在PeopleService类的构造方法中首先注入了IPeople接口实例,还注入了IServiceProvider的接口实例,然后在PeopleService类CreatePeople方法中,来使用IServiceProvider接口的实例来获取其它依赖注入的类。
using Microsoft.Extensions.DependencyInjection; namespace Net8DependencyInjection { interface IPeople { string? Name { get; set; } } class People : IPeople { private string? _name; public string? Name { get { return _name; } set { _name = value; } } } interface IPeopleService { IServiceProvider GetCurrentServiceProvider(); IPeople? CreatePeople(); } class PeopleService : IPeopleService, IDisposable { protected IServiceProvider _serviceProvider; protected IPeople _people; //因为PeopleService类由依赖注入DI创建,所以依赖注入DI可以给PeopleService类的构造方法注入IServiceProvider接口的实例,可以用它来获取其它依赖注入的类 public PeopleService(IPeople people, IServiceProvider serviceProvider) { _people = people; _serviceProvider = serviceProvider; } //用PeopleService类的构造方法注入的IServiceProvider接口实例,来获取其它依赖注入的类 public IPeople? CreatePeople() { return _serviceProvider.GetService<IPeople>(); } public void Dispose() { if (_serviceProvider is IDisposable) { Console.WriteLine("Disposing _serviceProvider ..."); IDisposable disposable = (IDisposable)_serviceProvider; disposable.Dispose(); } } //返回构造方法中依赖注入的IServiceProvider接口实例 public IServiceProvider GetCurrentServiceProvider() { return _serviceProvider; } } internal class Program { static void Main(string[] args) { IServiceCollection services = new ServiceCollection(); services.AddTransient<IPeople, People>(); //注册IPeople接口和People类的依赖注入关系 services.AddTransient<IPeopleService, PeopleService>(); //注册IPeopleService接口和PeopleService类的依赖注入关系 using (ServiceProvider rootServiceProvider = services.BuildServiceProvider()) { IPeopleService? rootPeopleService = rootServiceProvider.GetService<IPeopleService>(); IPeople? peopleInRoot = rootPeopleService?.CreatePeople(); peopleInRoot!.Name = "Jack"; Console.WriteLine("rootPeopleService.GetCurrentServiceProvider is {0}", rootPeopleService?.GetCurrentServiceProvider().GetType().ToString()); //rootPeopleService.GetCurrentServiceProvider is Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope Console.WriteLine("rootServiceProvider is {0}", rootServiceProvider.GetType().ToString()); //rootServiceProvider is Microsoft.Extensions.DependencyInjection.ServiceProvider Console.WriteLine("rootPeopleService.GetCurrentServiceProvider == rootServiceProvider is {0}", rootPeopleService?.GetCurrentServiceProvider() == rootServiceProvider); //rootPeopleService.GetCurrentServiceProvider == rootServiceProvider is False Console.WriteLine(); Console.WriteLine(); Console.WriteLine(); using (IServiceScope serviceScope = rootServiceProvider.CreateScope()) { IPeopleService? scopePeopleService = serviceScope.ServiceProvider.GetService<IPeopleService>(); IPeople? peopleInScope = scopePeopleService?.CreatePeople(); peopleInScope!.Name = "Tom"; Console.WriteLine("peopleInRoot == peopleInScope is {0}", peopleInRoot == peopleInScope); //peopleInRoot == peopleInScope is False Console.WriteLine("scopePeopleService.GetCurrentServiceProvider is {0}", scopePeopleService?.GetCurrentServiceProvider().GetType().ToString()); //scopePeopleService.GetCurrentServiceProvider is Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope Console.WriteLine("serviceScope.ServiceProvider is {0}", serviceScope.ServiceProvider.GetType().ToString()); //serviceScope.ServiceProvider is Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope Console.WriteLine("scopePeopleService.GetCurrentServiceProvider == serviceScope.ServiceProvider is {0}", scopePeopleService?.GetCurrentServiceProvider() == serviceScope.ServiceProvider); //scopePeopleService.GetCurrentServiceProvider == serviceScope.ServiceProvider is True Console.WriteLine("rootPeopleService.GetCurrentServiceProvider == serviceScope.ServiceProvider is {0}", rootPeopleService?.GetCurrentServiceProvider() == serviceScope.ServiceProvider); //rootPeopleService.GetCurrentServiceProvider == serviceScope.ServiceProvider is False } } Console.WriteLine("Press any key to end..."); Console.ReadLine(); } } }
上面的代码运行后,输出的结果如下所示:
rootPeopleService.GetCurrentServiceProvider is Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope rootServiceProvider is Microsoft.Extensions.DependencyInjection.ServiceProvider rootPeopleService.GetCurrentServiceProvider == rootServiceProvider is False peopleInRoot == peopleInScope is False scopePeopleService.GetCurrentServiceProvider is Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope serviceScope.ServiceProvider is Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope scopePeopleService.GetCurrentServiceProvider == serviceScope.ServiceProvider is True rootPeopleService.GetCurrentServiceProvider == serviceScope.ServiceProvider is False Disposing _serviceProvider ... Disposing _serviceProvider ... Press any key to end...
下面的这篇微软官方文档,还提到Microsoft.Extensions.DependencyInjection在使用依赖注入调用类的构造方法创建实例时,构造方法中可以包含非依赖注入关系的参数,但是这种参数必须要有默认值,否则会报错:
Constructor injection behavior
Constructors can accept arguments that aren't provided by dependency injection, but the arguments must assign default values.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
2019-01-17 SQLServer的TDE加密