Application of IOC in ASP. NET Web API

Source: Internet
Author: User

Reference page:

Http://www.yuanjiaocheng.net/webapi/create-crud-api-1-get.html

Http://www.yuanjiaocheng.net/webapi/create-crud-api-1-post.html

Http://www.yuanjiaocheng.net/webapi/create-crud-api-1-put.html

Http://www.yuanjiaocheng.net/webapi/create-crud-api-1-delete.html

Http://www.yuanjiaocheng.net/webapi/Consume-web-api.html

Control inversion (inversion of CONTROL,IOC), simply put, is that the application itself is not responsible for the creation and maintenance of dependent objects, but to an external container. The control is then transferred from the application to the external IOC container, and control realizes the so-called reversal. For example, an instance of type B needs to be used in type A, and a B instance is created not by a, but by an external container. It is of great significance to realize the activation of target httpcontroller by means of IOC. [This article has been synced to ' how ASP. NET Web API Works ']

I. IOC-based Httpcontrolleractivator

The purpose of applying IOC to the Httpcontroller activation system is to have a predefined IOC container to provide the final Httpcontroller object. How is the controller created with the ASP. NET Web API? "We know that Httpcontroller activation is ultimately done by the Httpcontrolleractivator object, so the IOC and ASP. The most straightforward way to integrate an API's Httpcontroller activation system is to customize a httpcontrolleractivator.

We demonstrate how to integrate with IOC through a simple example of customizing Httpcontrolleractivator, and the IOC framework we use is unity. We have defined this Unityhttpcontrolleractivator type in an ASP. NET Web API application. Unityhttpcontrolleractivator has a property unitycontainer that represents the Unity container, which is initialized in the constructor. In the Create method for the Httpcontroller created, we call the Resolve method of this UnityContainer object to create the target Httpcontroller object.

   1:publicclass Unityhttpcontrolleractivator:ihttpcontrolleractivator
   2: {
   3:      Public private set; }
   4:
   5:      Public Unityhttpcontrolleractivator (Iunitycontainer UnityContainer)
   6:     {        
   7:         this. UnityContainer = UnityContainer;
   8:     }
   9:
  Ten:      Public  Ihttpcontroller Create (httprequestmessage request, Httpcontrollerdescriptor Controllerdescriptor, Type Controllertype)
One   :     {
  :         return (Ihttpcontroller) this. Unitycontainer.resolve (Controllertype);
  :     }
  : }

Next we define the following Contactscontroller, which inherits from Apicontroller, to manage contact information. For simplicity, we only define a unique action method get to get contact information. The method has a default parameter ID that represents the ID of the contact that you want to get, and returns all contact lists if you do not provide this parameter.

   1:publicclass Contactscontroller:apicontroller
   2: {
   3:      Public private set; }
   4:      Public Contactscontroller (Icontactrepository repository)
   5:     {
   6:         this. Repository = Repository;
   7:     }
   8:      Public Ienumerable<contact> Get (string"")
   9:     {
  Ten:         return  This
One   :             string. IsNullOrEmpty (ID) | | id = = Contact. ID);
  :     }
  : }
  14:
  :publicclass Contact
  : {
  :      Public string Id {get; set;}
  :      Public string Name {get; set;}
  :      Public string Phoneno {get; set;}
  :      Public string EmailAddress {get; set;}
  £ º      Public string Address {get; set;}
  : }

The action method uses the object returned by the Repository property to implement the query work of the contact, which initializes the properties of the Icontactrepository interface type in the constructor. We use the Icontactrepository interface to abstract the storage of contact data, as shown in the following code snippet, where we define only the unique Getcontacts method to filter the corresponding list of contacts based on the specified additions.

   1:publicinterface icontactrepository
   2: {
   3:     Ienumerable<contact> getcontacts (predicate<contact> predicate);
   4: }

We define the following Defaultcontactrepository type as the default implementation of the Icontactrepository interface, for simplicity, we use a static dictionary to hold the contact list.

   1:publicclass Defaultcontactrepository:icontactrepository
   2: {
   3:     Private Static New List<contact>
   4:     {
   5:         New contact{id="001""Zhang San",  phoneno="123""[email protected]"},
   6:         New contact{id="002""John Doe",  phoneno="456""[email protected]"}
   7:     };
   8:
   9:      Public Ienumerable<contact> getcontacts (predicate<contact> predicate)
  Ten:     {
One   :         return contacts. Where (contact=>predicate (contact));
  :     }
  : }

We registered the custom Unityhttpcontrolleractivator in Global.asax. As shown in the following code snippet, we created a UnityContainer object in the Application_Start method and called the generic method registertype<tfrom,tto> A matching relationship between the Icontactrepository interface and the Defaultcontactrepository type is registered. We finally create a Unityhttpcontrolleractivator object based on this unitycontainer and register it on the current servicescontainer.

   1:publicclass WebApiApplication:System.Web.HttpApplication
   2: {
   3:     protected void Application_Start ()
   4:     {
   5:         //Other operations
   6:         New UnityContainer ();
   7:         unitycontainer.registertype<icontactrepository,   
   8:         GlobalConfiguration.Configuration.Services.Replace (typeofnew Unityhttpcontrolleractivator ( UnityContainer));
   9:     }
  Ten: }

When this ASP. NET Web API app runs, we can get all contact lists ("/api/contacts") and contact information for an ID of "001" ("/api/contacts/001") directly in the browser by entering the appropriate address. The corresponding contact information appears on the browser in the form shown.

Ii. IOC-based Dependencyresolver

Because the default defaulthttpcontrolleractivator will first use the currently registered Dependencyresolver object to activate the target Httpcontroller, So in addition to using the custom Httpcontrolleractivator to introduce IOC to the Httpcontroller activation system, another effective solution is to register the custom dependencyresolver.

The next dependencyresolver that will be customized is based on another IOC framework called "Ninject". Compared to Unity,ninject is a more lightweight IOC framework. As space is limited, we cannot introduce too much of this IOC framework, and interested readers can visit their official website ("http://www.ninject.org/") to learn about Ninject.

   1:publicclass Ninjectdependencyresolver:idependencyresolver
   2: {
   3:     Private New List<idisposable> ();
   4:      Public private set; }
   5:
   6:      Public Ninjectdependencyresolver (ninjectdependencyresolver parent)
   7:     {
   8:         this. Kernel = parent. Kernel;
   9: }
  10:
One   :      Public Ninjectdependencyresolver ()
  :     {
  :          This New Standardkernel ();
  :     }
  15:
  :      Public void where Tto:tfrom
  :     {
  :         this. Kernel.bind<tfrom> (). To<tto> ();
  : }
  20:
  £ º      Public Idependencyscope BeginScope ()
  :     {
At   :         return New Ninjectdependencyresolver (this);
  :     }
  25:
  £ º      Public Object GetService (Type servicetype)
  :     {
  :         return this. Kernel.tryget (servicetype);
  :     }
  30:
  £ º      Public ienumerable<Object> GetServices (Type servicetype)
  :     {
  :         foreach inch this. Kernel.getall (servicetype))
  :         {
  :             this. Adddisposableservice (service);
  £ º             yield return service;
  Panax Notoginseng:         }
  : }    
  39:
Max   :      Public void Dispose ()
  :     {
  £ º         foreach  in Disposableservices)
  :         {
  :             disposable. Dispose ();
  :         }
  : }
  47:
  :     Private void Adddisposableservice (object servie)
  £ º     {
  :          as IDisposable;
  Wuyi:         if (null ! = Disposable &&!disposableservices.contains (disposable))
  :         {
  :             disposableservices.add (disposable);
Wu   :         }
  :     }
  : }

We created a custom dependencyresolver such as the previous type Ninjectdependencyresolver. The core of Ninjectdependencyresolver is the read-only attribute kernel of type Ikernel, The GetService and GetServices methods used to get the service instance are implemented by invoking the Tryget and GetAll methods of this kernel property, respectively. The BeginScope method returns a new Ninjectdependencyresolver object that has the same kernel object as itself. We define the additional method register<tfrom,tto> to register the mapping between the interface and the implementation type. To ensure that the obtained service instance can be released normally, we define a list of element types as IDisposable. If the obtained object implements the IDisposable interface, it is put into this list, and we release all the objects in the list in the implemented Dispose method.

Now we apply this custom Ninjectdependencyresolver to the previous demo instance. We only need to replace the registration for the custom Httpcontrolleractivator in Global.asax with the registration for Ninjectdependencyresolver. After you run this ASP. NET Web API app and try to get contact information through the browser, we still get the results as shown.

   1:publicclass MvcApplication:System.Web.HttpApplication
   2: {
   3:     protected void Application_Start ()
   4:     {
   5:         //Other operations
   6:         New Ninjectdependencyresolver ();
   7:         dependencyresolver.register<icontactrepository, defaultcontactrepository> ();
   8:         
   9:     }
  Ten: }

Application of IOC in ASP. NET Web API

Related Article

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.