Using the IOC Trilogy in ASP. Two. Replace the IOC container with AUTOFAC and implement attribute injection)

Source: Internet
Author: User

Preface

This article focuses on the usage and injection type lifecycle of the IOC container that comes with it in ASP.

In this case, we will not dwell on what the IOC is and what di is. EMM: Do not know can self-Baidu.

Directory

Using the IOC Trilogy in ASP (I.. IOC container with ASP. NET Core)

Using the IOC Trilogy in ASP. Two. Replace the IOC container with AUTOFAC and implement attribute injection)

Using the IOC Trilogy in ASP. Three. Using the replaced AUTOFAC to implement AOP interception

Body

As we said in the previous article, the IOC container that comes with ASP. NET core is lightweight, not a lot of functionality, just a basic function.

So today we'll talk about how to replace the IOC container with AUTOFAC and implement the attribute injection

Note: This article requires the reader to understand the DI IOC and use the relevant framework.

1. Replace the default IOC container with AUTOFAC

First, we need to refer to the relevant package from NuGet.

Autofac

Autofac.Extensions.DependencyInjection (This package extends some of the Microsoft Services classes.) To facilitate the replacement of AUTOFAC)

Then, we modify the Configureservices code in startup as follows:

  public   IServiceProvider configureservices ( Iservicecollection services) {services.            Addmvc (); Services.            Adddbcontext  <bloggingcontext> (); Services.            Adddirectorybrowser ();  var  containerbuilder = new   Containerbuilder ();            Containerbuilder.registermodule  <defaultmodule> ();            Containerbuilder.populate (services);             var  container = Containerbuilder.build ();  return  new   Autofacserviceprovider (container); }

Here we use one of the functions of AUTOFAC, modular injection . That is registermodule here, Defaultmodule is our injection module, the code is very simple, as follows:

     Public class Defaultmodule:module    {        protectedoverridevoid  Load (containerbuilder builder)        {             // inject test service            Builder. Registertype<testservice> (). As<itestservice>();                    }    }

To explain, in the code above, we configure IServiceProvider resolves from the AUTOFAC container (sets a valid AUTOFAC service adapter).

It is then used throughout the framework to parse the controller dependencies and HttpContext All Other use cases are exposed on the service location.

This allows us to complete the preliminary AUTOFAC container replacement. Let's create a controller to see the effect. The code is as follows:

  Public classAutodicontroller:controller {Private ReadOnlyItestservice _testservice;  PublicAutodicontroller (Itestservice testservice) {_testservice=Testservice; }                //Get:autodi         PublicActionResult Index () {viewbag.date= _testservice.getlist ("Name"); returnView (); }}

when the framework (through a named Defaultcontrolleractivator Service ) to create an instance of a controller, it resolves IServiceProvider's all constructor dependencies. in the above code, it uses the AUTOFAC container to parse the resulting class.

This will enable us to initially achieve the effect of replacing the IOC container.

However, this process differs from ASP . The controller itself is not parsed from the container, so the service can only be parsed from its constructor parameters.

So. This process makes it impossible to use some of the more advanced features of AUTOFAC. For example, attribute injection is good or bad about attribute injection. belongs to the benevolent see of the beholder, here we don't discuss whether it is good or bad.)

2. How to use the advanced features of AUTOFAC, attribute injection.

Let's go back to the AUTOFAC Setup code and set the property injection as follows:

var New  // Modular injection of  containerbuilder.registermodule<defaultmodule>();   // attribute injection Controller  Containerbuilder.registertype<autodicontroller>(). Propertiesautowired ();  Containerbuilder.populate (services);

The code for the injected module is modified as follows:

// attribute is injected into builder. Registertype<testservice> (). As<itestservice> (). Propertiesautowired ();

Then modify our controller code as follows:

 Public class Autodicontroller:basecontroller {        public  getset;}                 // Get:autodi         Public actionresult Index ()        {            = _testservice.getlist ("Name");             return View ();        }
}

Here we have removed the controller's constructor function.

We run the code and find that _testservice is null, so there is no injection success at all. The reason for the failure we have already explained ... But let's just highlight it.

Although the Controller's constructor dependency will be determined by MVC from the IServiceProvider Solution (which is the example of our previous constructor injection),

But the instance of the controller itself (and its processing) is created and owned by the framework, not by the container.

So how do we change the creation and owner of the controller itself?

We'll find a way in Microsoft.Extensions.DependencyInjection. It's called addcontrollersasservices .

Its comments translate to the following: Converting the controller's host to the registered service (that is, the AUTOFAC we replaced).

However, note that: Although the owner of the control is changed to AUTOFAC, we still cannot use the associated attribute injection method.

So, let's go to GitHub and look at this method source code as follows. (This is the benefit of open source ...):

 Public StaticImvcbuilder Addcontrollersasservices ( ThisImvcbuilder Builder) {            if(Builder = =NULL)            {                Throw NewArgumentNullException (nameof (builder)); }            varFeature =Newcontrollerfeature (); Builder.            Partmanager.populatefeature (feature); foreach(varControllerinchFeature. Controllers.select (c =C.astype ())) {Builder.            Services.tryaddtransient (Controller, Controller); } builder. Services.replace (Servicedescriptor.transient<icontrolleractivator, servicebasedcontrolleractivator>()); returnBuilder; }

We'll find the last sentence.

Builder. Services.replace (Servicedescriptor.transient<icontrolleractivator, servicebasedcontrolleractivator> ());

it means using Servicebasedcontrolleractivator Replace Defaultcontrolleractivator (meaning that the framework will now try to Resolve the controller instance from IServiceProvider )

.. This is finally the truth.

We only need to modify the configuration service code as follows:

      PublicIServiceProvider configureservices (iservicecollection services) {//Replace controller ownerServices. Replace (Servicedescriptor.transient<icontrolleractivator, servicebasedcontrolleractivator>()); Services.            Addmvc (); Services. Adddbcontext<BloggingContext>(); Services.            Adddirectorybrowser (); varContainerbuilder =NewContainerbuilder (); Containerbuilder.registermodule<DefaultModule>(); //using attribute injection controllerContainerbuilder.registertype<autodicontroller>().            Propertiesautowired (); //containerbuilder.registertypes (feature. Controllers.select (Ti = ti). Astype ()). ToArray ()). Propertiesautowired ();containerbuilder.populate (services); varcontainer =Containerbuilder.build (); return NewAutofacserviceprovider (container); }

Note that the replacement method must be before ADDMVC:

Then we run our controller code. Effect:

, the _testservice has been instantiated. show that our attribute injection is successful.

written in the last

This is the end of this article, and next we explain how to use the advanced features of AUTOFAC to implement our aspect programming (AOP)

Like, please point a recommendation and attention, ~ There are problems and I hope you criticize.

Using the IOC Trilogy in ASP. Two. Replace the IOC container with AUTOFAC and implement attribute injection)

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.