An example of DI for ASP Web Forms

Source: Internet
Author: User

Compared to ASP. NET MVC and Web API, using Dependency injection in Web Forms applications is a bit of a hassle. Here is an example of how to inject dependent objects into the ASPX page of Web Forms.

Use the development tools and categories library:

    • Visual Studio 2013
    • . NET Framework 4.5
    • Unity 3.5.x


Problem description

For testing or other reasons, you want the ASPX Web page to depend only on the interface of a particular service, not on the representational category.

Suppose the home page Default.aspx needs a return "Hello world!" String service, and we name the interface of this service Ihelloservice. The following interfaces and implementation categories for this service:

Public interface ihelloservice{    string Hello (string name), public class helloservice:ihelloservice{public    string Hello (string name)    {        return "Hello," + Name;    }}

The Code-behind category of Default.aspx will probably look like this:

Public partial class default:system.web.ui.page{public    ihelloservice HelloService {get; set;}     protected void Page_Load (object sender, EventArgs e)    {        //outputs a string of messages on the Web page. Messages are provided by HelloService.        Response.Write (this. Helloservice.hello ("DI in ASP. NET Web forms!"));}    }

Here's the problem: Page objects are created by the ASP. NET Web Forms Framework, how do we inject ihelloservice objects from outside?


Solution

In general, we recommend using Constructor injection to inject dependent objects as much as possible, but this method is difficult to use on Web Forms page objects. A excision solution is to use Mark Seemann's "Private Birth Injection" (bastard injection), like this:

Public partial class default:system.web.ui.page{public    ihelloservice HelloService {get; set;}     Public Default ()    {        //Container objects are parsed through a common object. This        . HelloService = appshared.container.resolve<ihelloservice> ();    }     protected void Page_Load (object sender, EventArgs e)    {        //output A string of messages on the Web page. The contents of the message are provided by HelloService.        Response.Write (this. Helloservice.hello ("DI in ASP. NET Web forms!"));}    }

One problem with this solution is that you have to refer to the Di container's namespace in the Code-behind category of each ASPX page, and this becomes dependent on the specific Di container everywhere. We want to make it as good as possible to centralize the code that calls the DI container in a few places.


The next implementation step uses an HTTP handler to intercept the page object's build process so that the service required by the Page object is injected into the property injection immediately after the Page object is established.

Actually step

Step 1: Create a new project

Set up a new ASP. NET WEB Application project, target platform Select the. NET Framework 4.5, project name named: Webformsdemo.

Select Empty for the project template, and then tick "Web Forms" on the Add folder and core references for project.

After the project is established, join the Unity suite through the NuGet administrator.


Step 2: Registration type

Establish a DI container in the application's "combined root" and register the dependent type. Here you choose to deal with this in the Application_Start method of Global_asax.cs:

public class global:system.web.httpapplication{    protected void Application_Start (object sender, EventArgs e)    {        var container = new UnityContainer ();        application["Container"] = Container; Keep container objects in shared variables         //register type        container. Registertype<ihelloservice, helloservice> ();    }}

Step 3: Write an HTTP Handler


Create a subdirectory under the project root directory: Infrastructure, and then include a new category in this directory: UnityPageHandlerFactory.cs. Code:

public class unitypagehandlerfactory:system.web.ui.pagehandlerfactory{public override IHttpHandler GetHandler (HttpC Ontext context, String RequestType, String virtualpath, String path) {Page page = base.        GetHandler (context, RequestType, virtualpath, path) as Page; if (page! = null) {var container = context.            application["Container"] as Iunitycontainer; var properties = getinjectableproperties (page.             GetType ()); foreach (Var prop in properties) {try {var service = contain Er. Resolve (Prop.                    PropertyType); if (service! = null) {Prop.                    SetValue (page, service);                }} catch {//Can't parse type No, forget it.    }}} return page; } public static propertyinfo[] Getinjectableproperties (type type) {varProps = type. GetProperties (BindingFlags.Public | BindingFlags.Instance |        BINDINGFLAGS.DECLAREDONLY); if (props.            Length = = 0) {//incoming type if it is generated by the ASPX page, it is necessary to obtain its parent (Code-behind category). Props = type. Basetype.getproperties (BindingFlags.Public | BindingFlags.Instance |        BINDINGFLAGS.DECLAREDONLY);    } return props; }       }

The program says:

    • The ASP. NET WEB Forms framework calls this handler object's GetHandler method to create a Page object.
    • In the GetHandler method, the parent category is used to create the Page object, and then the property injection is processed immediately. First, remove the DI container created from the previous step from the application["Container", then find out which public properties the current Page object declares, then use the DI container to parse the type of each property one by one and assign the created object to the property.
    • The static method Getinjectableproperties finds all the public attributes declared by the specified type and returns it to the calling side. Note that this property injection only for the "public properties declared by the page class itself", so that it does not take time to handle the dozens of public properties inherited by the parent class.


Step 4: Registration of HTTP Handler

In Web. config, register the HTTP handler that you just wrote:

<configuration>  <system.web>    <compilation debug= "true" targetframework= "4.5"/>    

Part of the infrastructure to this step has been completed, and then the various ASPX pages are written.

Step 5: Write a test page

Add a new Web Form to the project named Default.aspx. It then declares the properties of the dependent service in the Code-behind category, and calls the method of the service elsewhere. Refer to the following example:

Public partial class default:system.web.ui.page{public    ihelloservice HelloService {get; set;}     protected void Page_Load (object sender, EventArgs e)    {        //outputs a string of messages on the Web page. Messages are provided by HelloService.        Response.Write (this. Helloservice.hello ("DI in ASP. NET Web forms!"));}    }

As you can see, the ASPX Web page does not need to reference the namespace of the Unity container, because the action of injecting dependent objects has been dealt with in advance by the infrastructure.


Step 6: Perform a look

When executed, the browser should display one line of messages: "hello, DI in ASP. Web forms!"

An example of DI for ASP Web Forms

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.