The "ASP. NET Core" Dependency Injection advanced gameplay-how to inject multiple service implementation classes

Source: Internet
Author: User
Tags httpcontext

Dependency injection plays an important role in the ASP, and is also a tall programming idea, and its general principle is: I want what, you give me what come over. Instances of the service type are automatically managed by the container without our explicit processing in the code.

So, with dependency injection, your programming mindset changes. In the past, many functional types (such as a cryptographic decryption class), we like to define it as static (static), and with dependency injection, you have to avoid the use of static type, should be handed over to the service container to help you manage, as long as you use well, you will find that dependency injection is very convenient.

The primary gameplay of dependency injection is also a more standard way to play, which has two modes:

1, ten generation only son mode: an interface corresponding to a class, such as the first definition of the interface IA, IB, then Class A implementation IA, Class B implementation of IB. One. It can also be an abstract class (or base Class) E, and then F inherits the Class E.

2, childlessness mode: Write a class directly, regardless of derivation, directly added to the service container.

Come on, look at an example.

I'll define an interface first.

     Public Interface Iplaygame    {        void  Play ();    }

Then, write a class to implement it.

     Public class Nbplaygame:iplaygame    {        publicvoid  Play ()        {            Console.WriteLine ("  A universal anesthetic. ");        }    }

We know that the so-called service class, in fact, is the ordinary class, these classes are generally used to complete certain functions, such as calculating MD5 value. Then, remember that the Startup class has a configureservices method, yes, in this guy, we just registered the service (is added to the Servicecollection collection).

         Public void configureservices (iservicecollection services)        {            services. AddTransient<iplaygame, nbplaygame>();        }

Add the time is very simple, type one-to-one, Iplaygame interface and Nbplaygame class corresponding. There are three ways to add a call, which actually corresponds to the life cycle of the service class in the container.

Addsingleton: Single instance, this is the longest life, with the day Shou. Only one instance is used in the entire application.

AddTransient: This is the most short-lived, may be every night overtime to stay up, die quickly. In this case, the instance of the service class is created when used and destroyed directly after use.

Addscoped: This is more difficult to understand. Its lifecycle is within a single request, including a subsequent child request between the client and the server, which is cleaned up as long as the requested session ends.

You can then inject, for example, in the middleware, on the controller, or on the constructors of other service classes (the middleware is on the Invoke/invokeasync method) for instance reception.

Now come on, write a middleware.

     Public class Testmiddleware    {        public  testmiddleware (requestdelegate next) {}        public   Iplaygame game)        {            game. Play ();             return task.completedtask;        }    }

The registered service is injected into the parameters of the InvokeAsync method. Note that the first parameter is HttpContext, which is the parameter that is required, followed by the injected parameter.

Finally, this middleware can be used in the Configure method of the Startup class.

         Public void Configure (Iapplicationbuilder app)        {            app. Usemiddleware<TestMiddleware>();        }

After running, the Play method is called, and the following results are output in the console.

"childlessness" mode, do not use the interface specification, direct write function class.

     Public class dosomething    {        publicstring" Hello, Boss looking for you just now." ";    }

Registering a service is simpler.

         Public void configureservices (iservicecollection services)        {            services. addscoped<DoSomething>();        }

Inject in the Configure method.

         Public void  dosomething thing)        {            Console.WriteLine (thing). GetMessage ());        }

After running, the output results are as follows.

In the container, use the Servicedescriptor class to store information about the service type. Where servicetype represents the type of service, if the service has an interface and an implementation class, then this attribute refers to the type of the interface, and the type information of the implementing class is stored by the Implementationtype attribute. If there is no interface, only the type is defined directly, then this type of information is stored on the ServiceType property, and the Implementationtype property is not used.

In the above examples, servicetype is Iplaygame interface related information, Implementationtype is the Nbplaygame class information. If, as in the case of the DoSomething class above, servicetype is dosomething related information, Implementationtype is empty.

Next, let's look at advanced gameplay.

Defines an interface.

     Public Interface Idemoservice    {        stringget;}         void Run ();    }

Then, there are two classes that implement this interface.

     Public classDemoservice1:idemoservice { Public stringVersion ="v1";  Public voidRun () {Console.WriteLine ("The first service implementation class. "); }    }     Public classDemoservice2:idemoservice { Public stringVersion ="v2";  Public voidRun () {Console.WriteLine ("A second service implementation class. "); }    }

Then we register the service.

         Public void configureservices (iservicecollection services)        {            services. AddTransient<idemoservice, demoservice1>();            Services. AddTransient<idemoservice, demoservice2>();        }

Then we routinely receive injections, and we still receive them using the method parameters of the middleware.

     Public class Demomiddleware    {        public  demomiddleware (requestdelegate next)        {            //  due to program conventions, This constructor must be provided.          }        publicasyncidemoservice sv)        {             await the context. Response.writeasync (SV. Version);        }    }

The middleware is then used in the Startup.configure method.

         Public void Configure (Iapplicationbuilder app, dosomething thing)        {            app. Usemiddleware<DemoMiddleware>();        }

After running, you find the problem and look at the output.

An accident, the parameter can only receive the last registered implementation type instance, namely the DemoService2 class. So I see a lot of friends on the Internet to ask,. NET Core does not support the injection of multiple service implementation classes? This baffled a lot of people.

To tell you the truth, core core is a support for injecting instances of multiple implementation classes.

Below, the old week to introduce two solutions (actually there are three kinds, there is a not very good, especially when you are not familiar with the Core brother, so I said two, basic enough).

Method One, receives the injection of the IServiceProvider type.

         Public AsyncTask InvokeAsync (HttpContext context, IServiceProvider provider) {StringBuilder sb=NewStringBuilder (); foreach(varSvinch provider. Getservices<idemoservice> ()) {sb. Append ($"{sv. Version}<br/>"); }            awaitcontext. Response.writeasync (sb.)        ToString ()); }

As long as the instance referenced by IServiceProvider can be received, multiple service instances can be obtained through the GetServices method.

Method Two, this method old week is recommended, simpler, directly injected ienumerable<t> type, in this case is ienumerable<idemoservice>.

         Public AsyncTask InvokeAsync (HttpContext context,ienumerable<idemoservice> SVS) {StringBuilder SB=NewStringBuilder (); foreach(varSvinchSVS) {sb. Append ($"{sv. Version}<br/>"); }            awaitcontext. Response.writeasync (sb.)        ToString ()); }

The beauty of ienumerable<t> is that it can be foreach, so you can access multiple instances and, if necessary, join LINQ together.

The results of the operation are as follows.

Don't ask me how I found out, anyway I told you, you use it.

Well, today's topic is here, 3166.

The "ASP. NET Core" Dependency Injection advanced gameplay-how to inject multiple service implementation classes

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.