[Asp.net 5] DependencyInjection project code analysis 4-Microsoft's implementation (5) (IEnumerable & lt; & gt; supplement ),

Source: Internet
Author: User

[Asp.net 5] DependencyInjection project code analysis 4-Microsoft's implementation (5) (IEnumerable <> supplement ),

For the dependency injection series of Asp.net 5, refer to [Asp.net 5] DependencyInjection project code analysis-directory

When talking about Microsoft's implementation earlier, we did not talk about OpenIEnumerableService and ClosedIEnumerableService. Now we can complete this part.

We recall that the IEnumerable and new OpenIEnumerableService (_ table) relationships are registered in the ServiceProvider class Constructor (used externally.

Public ServiceProvider (IEnumerable <ServiceDescriptor> serviceDescriptors) {_ root = this; _ table = new ServiceTable (serviceDescriptors); _ table. add (typeof (IServiceProvider), new ServiceProviderService (); _ table. add (typeof (IServiceScopeFactory), new ServiceScopeService (); _ table. add (typeof (IEnumerable <>), new OpenIEnumerableService (_ table ));}ServiceProvider Constructor

Because IEnumerable is generic, we can infer that the OpenIEnumerableService class should implement the IGenericService interface. So what is the process between the implementation classes of IEnumerable <T>?

  • [Step 1] First, the system will check whether the _ services (Dictionary <Type, ServiceEntry> Type) in ServiceTable has registered the IEnumerable <T> Type. If yes, the system will return the implementation class directly.Last. The following is why IEnumerable <T> is directly included:
    • The system can display the registered IEnumerable <T>, such as services. AddTransient <IEnumerable <T>, List <T> ();
    • The system may have previously obtained IEnumerable <T>, SO _ services has the cache of the previous result.
  • [Step 2] if the corresponding IEnumerable <T> is not found, the system will continue to use _ genericServices (Dictionary <Type, List <IGenericService> Type) to find IEnumerable <>, different from obtaining through _ services, the IGenericService List (List type, including order) corresponding to the IEnumerable <> type obtained through _ genericServices is not a single IGenericService; then traverse the IGenericService list in sequenceIEnumerable <T>/IGenericService. GetService ()Add to services, and repeat the [Step 1] operation to obtain.
    • If the system does not register the IEnumerable <> type, only the unique register item OpenIEnumerableService can be obtained in the _ genericServices list. The corresponding actions are performed in OpenIEnumerableService.
    • If the system registers the IEnumerable <> type (for example, GenericService1), GenericService1 must be placed after OpenIEnumerableService in the registration list. Therefore, when obtaining IEnumerable <T>, OpenIEnumerableService. the returned values of GetService () and GenericService1.GetService () must be added to _ services, but GenericService1.GetService () must be later. Therefore, the Implementation class of IEnumerable <T> must be GenericService1.GetService (). createCallSite (). invoke () value;In other words, GenericService1 will overwrite OpenIEnumerableService.
    • Because the registration of IEnumerable will overwrite the OpenIEnumerableService, in principle, you are not allowed to register IEnumerable <> type

OpenIEnumerableService and ClosedIEnumerableService

BecauseOpenIEnumerableServiceImplement the IGenericService interface. Therefore, an IService-type object is returned, which is of the ClosedIEnumerableService type. Within the ClosedIEnumerableService type, the registration items of all T of _ services in ServiceTable are actually returned, and then returned as IEnumerable <T> type.

Internal class OpenIEnumerableService: IGenericService {private readonly ServiceTable _ table; public OpenIEnumerableService (ServiceTable table) {_ table = table;} public ServiceLifetime Lifetime {get {return ServiceLifetime. transient ;}} public IService GetService (Type closedServiceType) {var itemType = closedServiceType. getTypeInfo (). genericTypeArguments [0]; ServiceEntry entry; return _ tabl E. TryGetEntry (itemType, out entry )? New ClosedIEnumerableService (itemType, entry): null ;}}OpenIEnumerableService internal class internal: IService {private readonly Type _ itemType; private readonly ServiceEntry _ serviceEntry; public ClosedIEnumerableService (Type itemType, ServiceEntry entry) {_ itemType = itemType; _ serviceEntry = entry ;} public IService Next {get; set;} public ServiceLifetime Lifetime {get {return ServiceLifetime. transient ;}} public IServiceCal LSite CreateCallSite (ServiceProvider provider, ISet <Type> callSiteChain) {var list = new List <IServiceCallSite> (); for (var service = _ serviceEntry. First; service! = Null; service = service. next) {list. add (provider. getResolveCallSite (service, callSiteChain);} return new CallSite (_ itemType, list. toArray ();} private class CallSite: IServiceCallSite {private readonly Type _ itemType; private readonly IServiceCallSite [] _ serviceCallSites; public CallSite (Type itemType, IServiceCallSite [] serviceCallSites) {_ itemType = itemType; _ serviceCallSites = serviceC AllSites;} public object Invoke (ServiceProvider provider) {var array = Array. CreateInstance (_ itemType, _ serviceCallSites. Length); for (var index = 0; index! = _ ServiceCallSites. length; ++ index) {array. setValue (_ serviceCallSites [index]. invoke (provider), index);} return array;} public Expression Build (Expression provider) {return Expression. newArrayInit (_ itemType, _ serviceCallSites. select (callSite => Expression. convert (callSite. build (provider), _ itemType )));}}}ClosedIEnumerableService

[Previously, when we introduced ServiceEntry, we clearly pointed out that it is a linked list structure, rather than storing a value separately. Its application has done its best here]

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.