AUTOFAC Official document (22) "Application integration MVC"

Source: Internet
Author: User
Tags reflection static class

AUTOFAC is always up to date to support the latest version of ASP.net MVC, so the documentation is kept up to date. Generally, the integration of each version remains fairly consistent.

MVC integration requires AUTOFAC.MVC5 NuGet packages.

The MVC set becomes the controller, the model binder, the action filter, and the view provides dependency injection integration. It also adds support for each request lifecycle.

This page explains the ASP.net classic MVC integration. If you are using ASP.net core, see the ASP.net core integration page.

    Quick Start
    Register Controllers
    Set the Dependency Resolver
    Register Model Binders
    Register Web Abstractions
    enable property injection for View Pages
    enable property injection for Action Filters
    Enable Inj Ection of Action Parameters
    Owin integration
    using "Plugin" assemblies
    using the current AUTOFAC Dependencyresolver
    Glimpse Integration Unit
    Testing
    Example
Quick Start

To integrate AUTOFAC with MVC, you need to reference the MVC Integration NuGet package, register your controller, and set up a dependency parser. You can also choose to enable other features.

protected void Application_Start ()
{
  var builder = new Containerbuilder ();

  Register your MVC controller. (Mvcapplication is the name of the class in Global.asax.) )
  Builder. Registercontrollers (typeof (Mvcapplication). Assembly);

  Optional: Register the Model binder Builder that requires di
  . Registermodelbinders (typeof (Mvcapplication). Assembly);
  Builder. Registermodelbinderprovider ();

  Optional: Register Web abstractions such as HttpContextBase.
  Builder. Registermodule<autofacwebtypesmodule> ();

  Optional: Enable property injection in the View page.
  Builder. Registersource (New Viewregistrationsource ());

  Optional: Enables property injection to the ation filter.
  Builder. Registerfilterprovider ();

  Optional: Enable action method parameter injection (RARE)
  Builder. Injectactioninvoker ();

  Set the dependency parser to AUTOFAC
  var container = Builder. Build ();
  Dependencyresolver.setresolver (new Autofacdependencyresolver (container));
}

The following sections detail the purpose of each feature and how to use it. Register Controller

When the application starts, you should register your MVC controller and its dependencies when building your AUTOFAC container. This usually occurs in the Application_Start method of the Owin startup class or Global.asax.

var builder = new Containerbuilder ();

You can use an assembly to scan a registered controller
once ... Builder. Registercontrollers (typeof (Mvcapplication). Assembly);

//... Or you can register your personal controller manually.
Builder. Registertype

Note that ASP.net MVC requests the controller through its specific type, so registering it as as<icontroller> () is incorrect. Also, if you register the controller manually and select the specified lifecycle, you must register them as instanceperdependency () or instanceperrequest ()-If you try to reuse the controller instance for multiple requests, ASP.net MVC throws an exception. Set Dependency resolver

After building your container, pass it to a new instance of the Autofacdependencyresolver class. Use the static Dependencyresolver.setresolver method to let ASP.net mvc know that it should use Autofacdependencyresolver to locate the service. This is the implementation of the AUTOFAC Idependencyresolver interface.

var container = Builder. Build ();
Dependencyresolver.setresolver (new Autofacdependencyresolver (container));

You can does this with the Registermodelbinders () method. must also remember to register the Autofacmodelbinderprovider using the Registermodelbinderprovider () . This is AUTOFAC ' s implementation of the Imodelbinderprovider interface. Registering model Bindings

An optional step you can take is to enable dependency injection for the model binder. Like the controller, model bindings (classes that implement Imodelbinder) can be registered in the container when the application starts. You can do this with the Registermodelbinders () method. You must also remember to register Autofacmodelbinderprovider using the Registermodelbinderprovider () extension method. This is the implementation of the AUTOFAC Imodelbinderprovider interface.

Builder. Registermodelbinders (assembly.getexecutingassembly ());
Builder. Registermodelbinderprovider ();

Because the registermodelbinders () extension method uses assembly scans to add model bindings, you need to specify the type of model binder (Imodelbinder implementation) to register.

This is done by using Autofac.Integration.Mvc.ModelBinderTypeAttribute, as follows:

[Modelbindertype (typeof (String)]
public class Stringbinder:imodelbinder
{public
  Override object Bindmodel (ControllerContext ControllerContext, Modelbindingcontext BindingContext)
  {
    //implemented in here
  }
}

Multiple instances of Modelbindertypeattribute can be added to a class if it is registered as multiple types of words. Registering web abstractions

MVC integration includes a AUTOFAC module that adds the registration of the HTTP request lifecycle to the Web abstract class. This will allow you to put web abstractions into your classes as dependencies and get the correct injection values at run time.

The following abstract class is included:

    HttpContextBase
    httprequestbase
    httpresponsebase
    httpserverutilitybase
    httpsessionstatebase
    Httpapplicationstatebase
    Httpbrowsercapabilitiesbase
    httpfilecollectionbase
    requestcontext
    httpcachepolicybase
    VirtualPathProvider
    Urlhelper

To use these abstractions, add autofacwebtypesmodule to the container using the standard Registermodule () method.

Builder. Registermodule<autofacwebtypesmodule> ();
enable attribute injection for the view page

By adding Viewregistrationsource to Containerbuilder before building the application container, you can make the property injection available for your MVC view.

Builder. Registersource (New Viewregistrationsource ());

Your view page must inherit from one of the base classes in which MVC supports creating views. This will be the Webviewpage class when using the Razor view engine.

Public abstract class Customviewpage:webviewpage
{public
  idependency Dependency {get; set;}
}

The Viewpage,viewmasterpage and Viewusercontrol classes are supported when you use the Web Forms view engine.

Public abstract class Customviewpage:viewpage
{public
  idependency Dependency {get; set;}
}

Make sure that your actual view page inherits from your custom base class. This can be accomplished using the @inherits directive in the. cshtml file of the Razor view engine:

@inherits Example.Views.Shared.CustomViewPage

When you use the Web Forms view engine, set the Inherits property in the @page directive in the. aspx file.

<%@ Page language= "C #" masterpagefile= "~/views/shared/site.master" inherits= " Example.Views.Shared.CustomViewPage "%>

Dependency injection is not available for Razor layout pages due to problems within the ASP.net mvc. The razor view will work, but the layout page will not. For more information, see Problem #349. enable attribute injection for action filters

To use property injection for your filter properties before building the container and providing it to autofacdependencyresolver, call the Registerfilterprovider () method on the Containerbuilder.

Builder. Registerfilterprovider ();

This allows you to add attributes to your filter properties, and any matching dependencies registered in the container will be injected into the attribute.

For example, the following action filter will inject the ILogger instance from the container (assuming you register a ilogger, note that the property itself does not need to be registered in the container.)

public class Customactionfilter:actionfilterattribute
{public
  ilogger Logger {get; set;}

  public override void OnActionExecuting (ActionExecutingContext filtercontext)
  {
    Logger.Log (" OnActionExecuting ");
  }
}

The same simple method applies to other Filter property types, such as authorization properties.

public class Customauthorizeattribute:authorizeattribute
{public
  ilogger Logger {get; set;}

  protected override bool Authorizecore (HttpContextBase HttpContext)
  {
    Logger.Log ("Authorizecore");
    return true;
  }

As usual, when you apply attributes to your actions, your work is done.

[Customactionfilter]
[Customauthorizeattribute]
Public ActionResult Index ()
{
}
enable inject action parameter

Although uncommon, some people want AUTOFAC to fill the arguments in the action method when called. It is recommended that you use constructor injection instead of action method injection on the controller, but you can enable action method injection if necessary:

AUTOFAC Extensibleactioninvoker attempts to parse parameters from the request lifecycle scope if the model binder cannot bind to parameters.
Builder. Registertype<extensibleactioninvoker> (). As<iactioninvoker> ();
Builder. Injectactioninvoker ();

Note that you can also use the Injectactioninvoker () mechanism with your own custom calling program.

Builder. Registertype<mycustomactioninvoker> (). As<iactioninvoker> ();
Builder. Injectactioninvoker ();
Owin Integration

If you use MVC as part of your Owin application, you need to do everything from the standard MVC integration-registering the controller, setting up a dependency resolver, and so on. Use the base AUTOFAC Owin integration to set up your application. Add a reference to the Autofac.Mvc5.Owin NuGet package. In your application startup class, register AUTOFAC MVC middleware After registering the underlying AUTOFAC middleware.

public class Startup
{public
  void Configuration (Iappbuilder app)
  {
    var builder = new Containerbuilder ( );


     Standard MVC settings: 
     //Register your MVC controller. 
    Builder. Registercontrollers (typeof (Mvcapplication). Assembly);

    Run other optional steps, such as registering the model binder, Web abstraction, and so on, and then setting the dependency parser to AUTOFAC.
    var container = Builder. Build ();
    Dependencyresolver.setresolver (new Autofacdependencyresolver (container));

   Owin MVC Setup:
   ///Register AUTOFAC middleware First, then register AUTOFAC MVC Middleware.
    app. Useautofacmiddleware (container);
    App. Useautofacmvc ();
  }

Minor problem: MVC cannot run 100% in the Owin pipeline. It still needs httpcontext.current and other things that are not owin. When an application starts, when MVC registers a route, it instantiates a icontrollerfactory and eventually creates two lifetime ranges of requests. It only happens when the application starts when the route is registered, not when the request begins to be processed, but it is something to be aware of. This is the product of two pipes being crushed together. We have studied some methods to try to solve this problem, but we can't do it in a clean way. using the Plugins assembly

If you have a controller that is not referenced by the main application in a "plugin assembly", you will need to register your controller plug-in assembly with ASP.net BuildManager.

You can do this by configuring or programming.

If you choose to configure, you need to add the plug-in assembly to the/configuration/system.web/compilation/assemblies list. If your plug-in assembly is not in the Bin folder, you also need to update the/configuration/runtime/assemblybinding/probing path.

<?xml version= "1.0" encoding= "Utf-8"?>
<configuration>
  <runtime>
    < assemblybinding xmlns= "Urn:schemas-microsoft-com:asm.v1" >
      <!--
          If you put your plugin into a folder that Isn ' t bin, add it to the probing path
      -->
      <probing privatepath= "Bin;bin\plugins"/>
    assemblybinding>
  </runtime>
  <system.web>
    <compilation>
      <assemblies >
        <add assembly= "The.Name.Of.Your.Plugin.Assembly.Here"/>
      </assemblies>
    </ compilation>
  </system.web>
</configuration>

If you choose to register programmatically, you need to perform during the pre-application startup period before ASP.net BuildManager starts.

Create an initialization class to perform assembly scan/load and register BuildManager:

Using System.IO;
Using System.Reflection;
Using System.Web.Compilation;

Namespace MyNamespace
{public
  static class initializer
  {public
    static void Initialize ()
    {
      var pluginfolder = new DirectoryInfo (Hostingenvironment.mappath ("~/plugins"));
      var pluginassemblies = pluginfolder.getfiles ("*.dll", searchoption.alldirectories);
      foreach (Var pluginassemblyfile in pluginassemblyfiles)
      {
        var asm = Assembly.LoadFrom ( Pluginassemblyfile.fullname);
        buildmanager.addreferencedassembly (ASM);}}}

Then make sure to use Assembly properties to register the start code before your application:

[Assembly:preapplicationstartmethod (typeof (initializer), "Initialize")]
Use the current AUTOFAC dependencyresolver

Once the MVC Dependencyresolver is set to Autofacdependencyresolver, You can use Autofacdependencyresolver.current as a shortcut to get the current dependency parser and convert it to autofacdependencyresolver.

Unfortunately, there are some problems with autofacdependencyresolver.current, which can lead to incorrect work. Typically, these problems add functionality by using a product such as glimpse or castle Dynamicproxy to "wrap" or "decorate" dependent parsers. If the current dependency parser is decorated or otherwise wrapped/proxied, it cannot be converted to autofacdependencyresolver, and there is no separate way to "unpack" or go to the actual parser.

Before AUTOFAC MVC integrated version 3.3.3, we tracked the current dependency parser by dynamically adding it to the request lifecycle scope. This makes it impossible to undo Autofacdependencyresolver from the broker, but this means that autofacdependencyresolver.current can only work during the life of the request-it cannot be used when the background task or application starts.

Starting with version 3.3.3, the logic for locating autofacdependencyresolver.current changes to first try to convert the current dependency parser, and then specifically look for flags that use Castle Dynamicproxy wrappers and open them by reflection. Without this ... We can't find the current autofacdependencyresolver, so we throw a InvalidOperationException exception,

The type of dependency parser is "Some.Other.DependencyResolver" but is expected to be of type "Autofac.Integration.Mvc.AutofacDependencyResolver". It is also not packaged by the Dynamicproxy in Castle project. This problem may be the result of a change in the Dynamicproxy implementation, or it may be because a different agent library is used to encapsulate the dependency parser.

This is typically the case when the action filter provider is used through Containerbuilder.registerfilterprovider (). The filter provider needs to access the AUTOFAC dependency resolver and use autofacdependencyresolver.current to perform this operation.

If you see this, this means that you are decorating the parser in a way that cannot be undone, and that a function dependent on autofacdependencyresolver.current will fail. The current solution is to not decorate the dependency parser. Glimpse Integration

When using AUTOFAC, integrating the MVC application with the glimpse is very similar to any other integration. However, if you use the action method parameter injection (for example, use Builder. Injectactioninvoker ()), glimpse perform the check will fail.

You can resolve this issue by adding the following content to the glimpse configuration:

  <glimpse defaultruntimepolicy= "on" endpointbaseuri= "~/glimpse.axd" >
    <inspectors>
      < ignoredtypes>
        <add type= "Glimpse.Mvc.Inspector.ExecutionInspector, Glimpse.mvc"/>
      </ ignoredtypes>
    </inspectors>
    <tabs>
      <ignoredTypes>
        <add type= " Glimpse.Mvc.Tab.Execution, Glimpse.mvc "/>
      </ignoredTypes>
    </tabs>
</glimpse >

Similarly, if you use the action parameter injection, you only need to do this. This is one of many reasons to recommend using the Controller constructor injection rather than the action method parameter injection. Unit Test

When a unit tests an application that uses AUTOFAC, and you have registered the Instanceperrequest component, you get an exception when you try to parse the components, because there is no HTTP request lifecycle during unit testing.

Each request lifetime Scope topic outlines the strategies for testing and troubleshooting each of the request-scope components.

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.