[ASP. 5] Dependencyinjection Project Code Analysis 4-Microsoft implementation (5) (ienumerable<> supplement)

Source: Internet
Author: User

The Dependency Injection injection series for ASP. NET 5 can refer to the link: [ASP. 5] dependencyinjection Project Code Analysis-Catalog

When we spoke about the implementation of Microsoft, we did not say anything about Openienumerableservice and Closedienumerableservice, and now we are going to add that part to the complete.

We recall that the ienumerable<>, new Openienumerableservice (_table) relationship is registered in the ServiceProvider class's constructor (for external use).

         PublicServiceProvider (ienumerable<servicedescriptor>servicedescriptors) {_root= This; _table=Newservicetable (servicedescriptors); _table. ADD (typeof(IServiceProvider),NewServiceproviderservice ()); _table. ADD (typeof(Iservicescopefactory),NewServicescopeservice ()); _table. ADD (typeof(ienumerable<>),NewOpenienumerableservice (_table)); }
ServiceProvider constructor Function

Because IEnumerable is generic, we can infer that the Openienumerableservice class should implement the Igenericservice interface. So what happens if we want to find the middle of the ienumerable<t> implementation class?

  • [Step 1] First, the system will look for _services (Dictionary<type, serviceentry> type) in the servicetable, if there are any registered ienumerable<t> types, If there is a registration directly return the last one in the implementation class. Here are the reasons for the direct inclusion of ienumerable<t>
    • The system can display the registration IENUMERABLE<T>, such as services. Addtransient<ienumerable<t>, list<t>> ();
    • The system may have previously obtained ienumerable<t>, so there is a cache of the last result in _services.
  • [Step 2] if the corresponding Ienumerable<t> is not found, the system will continue through _genericservices (Dictionary<type, list<igenericservice>> Type) to find Ienumerable<>, and to get different through _services way, through _genericservices will get all registered ienumerable<> The Igenericservice list for the type (list type, containing order) is not a single igenericservice, and then the Igenericservice list is traversed sequentially, ienumerable<t>/ The correspondence of Igenericservice.getservice () is added to the services, which is obtained by repeating [step 1].
      • If the system does not register an additional ienumerable<> type, only the unique registry entry Openienumerableservice is available in the _genericservices list. Then the corresponding operation is carried out in the Openienumerableservice.
      • If the system registers an additional ienumerable<> type (assuming GenericService1), then GenericService1 must be ranked behind Openienumerableservice in the registration list. So when you get ienumerable<t>, the Openienumerableservice.getservice () and Genericservice1.getservice () return values are bound to be added to _ Services, but Genericservice1.getservice () must be in the back, so the Ienumerable<t> implementation class must be Genericservice1.getservice (). Createcallsite (). The value of the Invoke (), in other words GenericService1 will overwrite the openienumerableservice.
      • Because the registration ienumerable<> will overwrite the openienumerableservice, it is not allowed to register the ienumerable<> type in principle

Openienumerableservice and Closedienumerableservice

Because Openienumerableservice implements the Igenericservice interface, an object of type IService is returned, which is the Closedienumerableservice type. The Closedienumerableservice type internally actually returns the registration entries for all T _services in servicetable, followed by the ienumerable<t> type.

    Internal classOpenienumerableservice:igenericservice {Private ReadOnlyservicetable _table;  Publicopenienumerableservice (servicetable table) {_table=table; }         Publicservicelifetime Lifetime {Get{returnservicelifetime.transient;} }         Publiciservice GetService (Type closedservicetype) {varItemType = Closedservicetype.gettypeinfo (). generictypearguments[0];            Serviceentry entry; return_table. Trygetentry (ItemType, outEntry)?NewClosedienumerableservice (ItemType, entry):NULL; }    }
Openienumerableservice
    Internal classClosedienumerableservice:iservice {Private ReadOnlyType _itemtype; Private ReadOnlyServiceentry _serviceentry;  PublicClosedienumerableservice (Type itemType, serviceentry entry) {_itemtype=ItemType; _serviceentry=entry; }         PublicIService Next {Get;Set; }  Publicservicelifetime Lifetime {Get{returnservicelifetime.transient;} }         PublicIservicecallsite Createcallsite (serviceprovider provider, iset<type>Callsitechain) {            varList =NewList<iservicecallsite>();  for(varService = _serviceentry.first; Service! =NULL; Service =service. Next) {list. ADD (provider.            Getresolvecallsite (service, callsitechain)); }            return NewCallSite (_itemtype, list.        ToArray ()); }        Private classCallsite:iservicecallsite {Private ReadOnlyType _itemtype; Private ReadOnlyiservicecallsite[] _servicecallsites;  PublicCallSite (Type itemType, iservicecallsite[] servicecallsites) {_itemtype=ItemType; _servicecallsites=servicecallsites; }             Public ObjectInvoke (serviceprovider provider) {varArray =array.createinstance (_itemtype, _servicecallsites.length);  for(varindex =0; Index! = _servicecallsites.length; ++index) {Array. SetValue (_servicecallsites[index].                Invoke (provider), index); }                returnArray; }             Publicexpression Build (expression provider) {returnExpression.newarrayinit (_itemtype, _servicecallsites.select (CallSite=Expression.convert (Callsite.build (provider),            (_itemtype))); }        }    }
Closedienumerableservice

[Before we introduced Serviceentry, it was clearly pointed out that it was a linked list structure, not a single value;

[ASP. 5] dependencyinjection Project Code Analysis 4-Microsoft implementation (5) (ienumerable<> supplement)

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.