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.

 

来源链接:https://www.cnblogs.com/OpenCoder/p/18676877

请登录后发表评论

    没有回复内容