[ASP. 5] Dependencyinjection Project Code Analysis 3-ninject

Source: Internet
Author: User

Microsoft.Framework.DependencyInjection.Ninject

The project contains a total of 5 classes of files, the underlying use of ninject implementation of dependency injection, the project is as follows:

As you can see from the file name,ninjectserviceprovider and ninjectservicescopefactory are interface IServiceProvider and The implementation class of the iservicescopefactory .

( The implementation class of the Iservicescope interface acts as ninjectservicescopefactory Internal classes exist, not as separate files. )

The entrance to the project is still the Ninjectregistration class at the end of the registration.

Ninjectregistration

The file code is as follows

  Public Static classninjectregistration { Public Static voidPopulate ( ThisIkernel Kernel, ienumerable<servicedescriptor>descriptors) {kernel. Load (NewServiceproviderninjectmodule (descriptors)); }         Public StaticIbindingnamedwithoronsyntax<t> inrequestscope<t>(                 ThisIbindingwheninnamedwithoronsyntax<t>binding) {            returnBinding. InScope (context =context.        Parameters.getscopeparameter ()); }        Internal StaticScopeparameter Getscopeparameter ( ThisIenumerable<iparameter>parameters) {            return( scopeparameter) (parameters. Where (P= = P.name = =typeof(Scopeparameter). FullName).        Singleordefault ()); }        Internal StaticIenumerable<iparameter>Addorreplacescopeparameter ( ThisIenumerable<iparameter>parameters, Scopeparameter scopeparameter) {            returnparameters. Where (P= = P.name! =typeof(Scopeparameter). FullName). Concat (New[] {scopeparameter}); }    }

static method:

Populate: The role is to register Serviceproviderninjectmodule in the kernel. For Ninject Most of the time, a custom inherited from the Ninjectmodule class is registered to the kernel, and the inherited class is used to manage dependency injection.

Getscopeparameter: Get parameters of all "scopeparameter" types

Addorreplacescopeparameter: Gets all the "scopeparameter" parameters and replaces it with the incoming "Scopeparameter".

Inrequestscope: In "binding." InScope "To add" Scopeparameter ".

In general, the file is an auxiliary method and an externally initialized interface.

Serviceproviderninjectmodule

The file code is as follows:

Internal classServiceproviderninjectmodule:ninjectmodule {Private ReadOnlyIenumerable<servicedescriptor>_servicedescriptors;  PublicServiceproviderninjectmodule (IEnumerable<ServiceDescriptor>servicedescriptors) {_servicedescriptors=servicedescriptors; }         Public Override voidLoad () {foreach(varDescriptorinch_servicedescriptors) {Ibindingwheninnamedwithoronsyntax<Object>binding; if(Descriptor. Implementationtype! =NULL) {Binding=Bind (Descriptor. servicetype). to (descriptor.                Implementationtype); }                Else if(Descriptor. Implementationfactory! =NULL) {Binding= Bind (descriptor. servicetype). Tomethod (context =                    {                        varServiceProvider = context. Kernel.get<iserviceprovider>(); returnDescriptor.                    Implementationfactory (serviceprovider);                }); }                Else{Binding=Bind (Descriptor. servicetype). Toconstant (descriptor.                Implementationinstance); }                Switch(descriptor. Lifetime) { CaseServiceLifetime.Singleton:binding.                        Insingletonscope ();  Break;  CaseServiceLifetime.Scoped:binding.                        Inrequestscope ();  Break;  CaseServiceLifetime.Transient:binding.                        Intransientscope ();  Break; }} Bind<IServiceProvider> (). Tomethod (context =            {                varResolver = context. Kernel.get<iresolutionroot>(); varInheritedparams = context. Parameters.where (p =P.shouldinherit); varScopeparam =NewScopeparameter (); Inheritedparams=Inheritedparams.addorreplacescopeparameter (Scopeparam); return NewNinjectserviceprovider (resolver, Inheritedparams.toarray ()); }).            Inrequestscope (); Bind<IServiceScopeFactory> (). Tomethod (context =            {                return Newninjectservicescopefactory (context); }).        Inrequestscope (); }    }
View Code

Although the amount of code is relatively small, the internal logic is simple.

First, by convention, the ienumerable<servicedescriptor> type parameter that represents the dependency injection relationship is passed in.

The Load method is then overloaded, and the dependency injection relationship is initialized according to Ienumerable<servicedescriptor> when the kernel is called.

The Load method first iterates through the ienumerable<servicedescriptor> for each Servicedescriptor object, by implementing the class type, implementing the class factory, implementing the order of the class instance, and then setting the corresponding life cycle. The last injected IServiceProvider is Ninjectserviceprovider, Iservicescopefactory is the ninjectservicescopefactory type.

* It is important to note that the Ninjectserviceprovider and Ninjectservicescopefactory injection range is scope, And the Scopeparam parameter is replaced for each ninjectserviceprovider to guarantee its scope range.

Ninjectserviceprovider

Internal classNinjectserviceprovider:iserviceprovider {Private Static ReadOnlyMethodInfo _getall; Private ReadOnlyIresolutionroot _resolver; Private ReadOnlyiparameter[] _inheritedparameters; Private ReadOnly Object[] _getallparameters; StaticNinjectserviceprovider () {_getall=typeof(resolutionextensions). GetMethod ("GetAll",NewType[] {typeof(Iresolutionroot),typeof(iparameter[])}); }         PublicNinjectserviceprovider (iresolutionroot resolver, iparameter[] inheritedparameters) {_resolver =Resolver; _inheritedparameters=inheritedparameters; _getallparameters=New Object[] {resolver, inheritedparameters}; }         Public ObjectGetService (Type type) {returnGetsingleservice (type)??GetLast (GetAll (type))??getmultiservice (type); }        Private Objectgetsingleservice (type type); PrivateIEnumerable Getmultiservice (Type collectiontype); PrivateIEnumerable GetAll (type type); Private Static ObjectGetLast (IEnumerable services); }

The class first initializes a static constructor when the class file is loaded, and the generic extension method "Ienumerable<t> getall<t> (this iresolutionroot root, params iparameter[] Parameters) "is assigned to the internal variable" _getall ". After the class constructor is initialized, the constructor assigns a value of Iresolutionroot _resolver (the inner core control class that relies on injection), iparameter[] _inheritedparameters assignment, and is "_getall" The parameters of the _getallparameters are initialized.

The system calls the GetService (Type) method when the system obtains an instance of the implementation class.

    • The system first calls getsingleservice[internal for _resolver. Tryget (Type, _inheritedparameters)], gets the implementation of the simple type.
    • Gets the data for the generic type, if the simple type is empty. Replace the T-type of the GetAll method with the actual type, then get all instances of that type, and finally go to the last of all instances.
Private IEnumerable GetAll (type type)        {            var getAll = _getall.makegenericmethod (type);             return (IEnumerable) Getall.invoke (null, _getallparameters);        }
    • If all instances of this type are still empty, then the type of type may be ienumerable<t> type, then the type T is obtained, and the GetAll method is called.

Ninjectservicescopefactory and Ninjectservicescope

Here both classes inherit from Iservicescopefactory and Iservicescope.

Ninjectservicescopefactory only created the Ninjectservicescope object internally, the code is as follows:

 Public ninjectservicescopefactory (IContext context)        {            = context. Kernel.get<iresolutionroot>();             = Context. Parameters.where (p = p.shouldinherit);        }          Public iservicescope createscope ()        {            returnnew  ninjectservicescope (_resolver, _inheritedparameters);        }

Within Ninjectservicescope, each time a Ninjectserviceprovider instance is built with the new Scopeparameter parameter to ensure that a new scope is opened each time. The code is as follows:

 Public ninjectservicescope (                iresolutionroot Resolver,                IEnumerable<IParameter>  Inheritedparameters)            {                new  scopeparameter ();                 = Inheritedparameters.addorreplacescopeparameter (_scope);                 New Ninjectserviceprovider (resolver, Inheritedparameters.toarray ());            }
*addorreplacescopeparameter when the Scopeparameter type parameter is present, it is replaced with _scope, which is not present when it is added.

[ASP. 5] Dependencyinjection Project Code Analysis 3-ninject

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.