Then the previous article is now a clear explanation of the relevant classes. So how does the framework specifically instantiate it? How the whole process is going to be.
We refer to the test folder in the source code to see:
varCollection =Newservicecollection (); collection. AddTransient<DependOnNonexistentService>();varProvider =Createserviceprovider (collection);protected OverrideIServiceProvider Createserviceprovider (iservicecollection collection) =collection. Buildserviceprovider (); Public StaticServiceProvider Buildserviceprovider ( Thisiservicecollection Services) { returnBuildserviceprovider (services, Serviceprovideroptions.default);} Public classserviceprovideroptions{//Avoid allocating objects in the default case Internal Static ReadOnlyServiceprovideroptions Default =Newserviceprovideroptions (); /// <summary> /// <c>true</c>To perform check verifying this scoped services never gets resolved from root provider; otherwise<c>false</c>. /// </summary> Public BOOLValidatescopes {Get;Set; } InternalServiceprovidermode Mode {Get;Set; } =serviceprovidermode.dynamic;}Internal enumserviceprovidermode{Dynamic, Runtime, Expressions, ilemit} Public StaticServiceProvider Buildserviceprovider ( Thisiservicecollection Services, serviceprovideroptions options) { if(Services = =NULL) { Throw NewArgumentNullException (nameof (services)); } if(Options = =NULL) { Throw NewArgumentNullException (nameof (options)); } return Newserviceprovider (services, options);}InternalServiceProvider (ienumerable<servicedescriptor>servicedescriptors, serviceprovideroptions options) {Iserviceproviderenginecallback callback=NULL; if(options.) Validatescopes) {Callback= This; _callsitevalidator=NewCallsitevalidator (); } Switch(options.) Mode) { Caseserviceprovidermode.dynamic: _engine=NewDynamicserviceproviderengine (Servicedescriptors, callback); Break; Caseserviceprovidermode.runtime: _engine=NewRuntimeserviceproviderengine (Servicedescriptors, callback); Break;#ifIl_emit Caseserviceprovidermode.ilemit: _engine=NewIlemitserviceproviderengine (Servicedescriptors, callback); Break;#endif Caseserviceprovidermode.expressions: _engine=NewExpressionsserviceproviderengine (Servicedescriptors, callback); Break; default: Throw NewNotSupportedException (nameof (options). Mode)); }}
View Code
As shown above, it is the entire process of injecting services and instantiating services. We builserviceprovider call the ServiceProvider class based on the Iservicecollection extension method, and then instantiate the related service.
In addition to implementing serviceprovider in this way, there is a defaultserviceproviderfactory in the default ASP. NET Core framework. However, this factory class is finally the extension method that calls the Iservicecollection interface--buildserviceprovider to create the ServiceProvider class.
Summarize:
The Iservicecollection interface extension method Addxxx collects the services that need to be injected, the service implementation type, and the service lifecycle. These are the property objects of the class that are obtained in servicedescriptor. This is also the explanation that Iservicecollection inherits from Ilist<servicedescriptor>. Then get the Serviceprovideroptions enumeration object, select the type that implements the instantiation, such as reflection. Finally, call Buildserviceprovider to generate the serviceprovider. ServiceProvider the service according to the selection and configuration prior to selection.
A rough anatomy of the whole process of ASP. NET core Dependency Injection (2)