[Dot Net Core](Graphic series )3. How to actually implement DI Resolve Service

Czxdas
3 min readJan 3, 2022

The previous section introduced how .Net Core prepares objects related to IOC in advance, which can be used by the program to call the Provider method to Resolve Service. This section will introduce how to actually Resolve Service after the call.

Let’s look at the following first:

IOC In Dot Net Core - ServiceProviderEngineScope GetService

When the selected Provider is ServiceProviderEngineScope, you can call GetService to perform Resolve. Step S1 in the figure is the first call, and then it will go to the part of the engine, that is, ServiceProviderEngine, which is also the function that calls GetService, as in step S2, it will look for the collection of RealizedService. This collection stores the delegate letter of the registered service corresponding to Resolve. If you have not Resolve, you need to call CreateServiceAccessor to obtain the corresponding CallSite object by CallSiteFactory.GetCallSite. CallSiteFactory.GetCallSite will first go to the CallSiteFactory._cacheCallSite collection to find if there is a corresponding CallSite object, if not, call the CallSiteFactory.CreateCallSite function to add it.

When the CallSite object is created according to the previously registered service information, as shown in Figure S3, a verification will be performed, which is to simulate an actual Resolve to see if there is an error. If there is an error, throw exception to handle.

Next, execute the DynamicServiceProviderEngine.RealizeService function, which will return a delegated event for GetService in step S1 to call.
The step in Figure S5 is to execute the RealizeService function, and its parameter is the ServiceProviderEngineScope itself.

With the difference of CallSite.kind, the route of calling CallSiteRuntimeResolver is also different.

The following figure takes CallSite.kind as Constructor as an example:

CallSite.kind is Constructor

The S5 step call will call the function in the CallSiteRuntimeResolver category, and the path is:
Resolve> VisitCallSite> VisitRootCache> VisitCache> VisitCallSiteMain> VisitConstructor

If you go to VisitConstructor, you must find the ConstructorCallSite object of this service to perform Resolve and generate entities.

By the way, if the Constructor parameter has other objects that also require DI, it will recursively call VisitCallSite in the VisitCallSiteMain of the call path until all the parameters are resolved.

The following figure takes CallSite.kind as the Factory as an example:

CallSite.kind is Factory

CallSite.kind is a factory, which means that the registration service was originally performed by a delegated function, and it is hoped that the actual service will generate an entity with a delegated function designed by itself.
The S5 step call will call the function in the CallSiteRuntimeResolver category, and the path is:
Resolve> VisitCallSite> VisitRootCache> VisitCache> VisitCallSiteMain> VisitFactory

If you go to VisitFactory, you must find the FactoryCallSite object of this service to execute Resolve, that is, use the delegate function originally registered in the ServiceDescriptor to generate the entity.

GetService depends on what Provider is. If it is DynamicServiceProviderEngine, it will go to IOC. To
For example, the StartUp class does not follow the IOC, and the parameter object in its constructor needs to execute GetService as the HostServiceProvider.

GetService decides which case to run is collected by registering to the ServiceDescriptor when registering, and they are all in the information in system.type.

Finally, when the ServiceCallSite is obtained in GetService, the corresponding type of callSite (ConstantCallSite, FactoryCallSite, ConstructorCallSite) is generated after the judgment of this information
Type.GetTypeInfo() .

You can see if the relevant information includes whether there is a constructor, what methods, public or private, and component information are included.

--

--