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 troublesome. Here is an example of how to inject dependent objects into the ASPX page of Web Forms.

Using the development tool and the category:

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


Question Description

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

Home Default.aspx need a biography "hello world!" string of services, and we name the interface of this service Ihelloservice. The following are the interfaces to this service:

 Public Interface ihelloservice{    string Hello (stringpublicclass  helloservice:ihelloservice{    publicstring Hello (string  name)    {        return"" + name;    }}

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

 Public Partial classdefault:system.web.ui.page{ PublicIhelloservice HelloService {Get;Set; } protected voidPage_Load (Objectsender, EventArgs e) {        //output A string of messages on the Web page. Messages are provided by HelloService. Response.Write ( This. Helloservice.hello ("DI in ASP. NET Web forms!")); }}

The question is: 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, but this method is very difficult to use on Web Forms page objects. A excision solution is to use the "Private Injection" (bastard injection) that Mark Seemann says, like this:

 Public Partial classdefault:system.web.ui.page{ PublicIhelloservice HelloService {Get;Set; }  PublicDefault () {//parse dependent objects through a common Container object.          This. HelloService = appshared.container.resolve<ihelloservice>(); }     protected voidPage_Load (Objectsender, EventArgs e) {        //output A string of messages on the Web page. Messages are provided by HelloService. Response.Write ( This. Helloservice.hello ("DI in ASP. NET Web forms!")); }}

One of the problems with this solution is that you must refer to the name space of the DI container in the Code-behind category of each ASPX page, and this becomes dependent on the specific DI container. We hope that the code that calls the DI container can be concentrated in a few places.


The next step is to use an HTTP handler to suspend the set-up of the Page object, so that the Page object needs to be injected into the service immediately after it is established, in the form of a property injection.

actual step

step 1: Creating a new case

Building a new ASP. NET Web Application, the target platform chooses the. NET Framework 4.5, and the project name is named: Webformsdemo.

Select Empty, and then tick "web forms" on the Add folder and core references for item. After the

case was established, the NuGet manager joined the Unity Suite.

step 2: Registration type

Establish a DI container in the application's "combined root" and register the dependency type. Here we 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  Span style= "color: #000000;" > sender, EventArgs e) { var  container = new   UnityContainer (); application[  container   "] = container; //  //  registration type  container.    Registertype<ihelloservice, Helloservice> (); }}

Step 3: Write an HTTP Handler


Create a subdirectory under the project root: Infrastructure, and then add a new category to this list: UnityPageHandlerFactory.cs. Code:

 Public classunitypagehandlerfactory:system.web.ui.pagehandlerfactory{ Public OverrideIHttpHandler GetHandler (HttpContext context,stringRequestType,stringVirtualPath,stringpath) {Page page=Base. GetHandler (context, RequestType, virtualpath, Path) asPage; if(Page! =NULL)        {            varContainer = context. application["Container"] asIunitycontainer; varProperties =getinjectableproperties (page.             GetType ()); foreach(varPropinchproperties) {                Try                {                    varService =container. Resolve (Prop.                    PropertyType); if(Service! =NULL) {Prop.                    SetValue (page, service); }                }                Catch                {                    //No way to parse the type is not to forget.                 }            }        }        returnpage; }      Public Staticpropertyinfo[] getinjectableproperties (type type) {varProps = type. GetProperties (BindingFlags.Public | BindingFlags.Instance |bindingflags.declaredonly); if(Props. Length = =0)        {            //if the type of the Code-behind is generated by the ASPX page, then it is necessary to obtain the nature of its parent (or category). Props = type. Basetype.getproperties (BindingFlags.Public | BindingFlags.Instance |bindingflags.declaredonly); }        returnprops; }       }

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 is used to create the Page object, and then the property injection is connected. First, remove the DI container created by the previous step from the application["Container", then find out what the current Page object declares to be public, and then use the DI container to parse the type of each one by one, and assign the created object to its own nature.
    • The Getinjectableproperties method will find out all the public claims declared by the specified type, and pass it back to the calling end. Note here that only the public property declared by the "page category itself" comes into the injection, so that it does not take time for the 10 public to be inherited by the parent.


Step 4: Registration of HTTP Handler

Register your HTTP handler in Web. config just before you write it:

<Configuration>  <system.web>    <compilationDebug= "true"targetframework= "4.5" />    <HttpRuntimetargetframework= "4.5" />  </system.web>   <system.webserver>    <handlers>      <Addname= "Unitypagehandlerfactory"Path= "*.aspx"verb="*"type= "WebFormsDemo.Infrastructure.UnityPageHandlerFactory"/>    </handlers>  </system.webserver></Configuration>

Part of the foundation has been completed by this step, and then the ASPX pages are written.

Step 5: Write a test page

Add a new Web Form to the case named Default.aspx. Then, in the Code-behind category, declare the dependencies of the dependent service and call the method of service elsewhere. Consider the following examples:

 Public Partial classdefault:system.web.ui.page{ PublicIhelloservice HelloService {Get;Set; } protected voidPage_Load (Objectsender, EventArgs e) {        //output 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 does not need to refer to the name space of the Unity container, because the action of injecting dependent objects has been built by the base to help you.


Step 6: Perform a look

When you do this, the browser should display a message: "hello, DI in ASP. Web forms!"

Happy coding!

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.