How to use dependency injection in WEBAPI

Source: Internet
Author: User
This article is going to share with you how dependency injection is used in Webapi, dependency injection is commonly used in interfaces, and is used more frequently in the actual work, so here are two ways to share the dependency injection in the API Ninject and unity. Let's take a look at the little series.

This article is going to share with you how dependency injection is used in Webapi, dependency injection is commonly used in interfaces, and is used more frequently in the actual work, so here are two ways to share the dependency injection in the API Ninject and unity Because the fast New year this period of time intends to understand the next vue.js, so after the face of Webapi share article may be slow update, hope to support a lot of friends understanding, after all, only continue to recharge learning, to better adapt IT industry bar, the content of this chapter hope you like, but also hope that you many sweep code support and recommend thank you:

»task Parallel Task Crawl Blog Home Information

The use of»IOC frame Ninject

»IOC Framework Unity's use

The following step by step to share:

»task Parallel Task Crawl Blog Home Information

First, we need to create a blog information entity class Moblog, the entity class code is as follows:

public class Moblog {public  moblog () {}///<summary>//  author nickname///  </summary>  Public String Nickname {get; set;}  <summary>///title///  </summary> public  string Title {get; set;}  <summary>////  The text address///  </summary> public  string Url {get; set;}  <summary>//description////  </summary> public  string Des {get; set;}  <summary>///  Avatar Image Address///  </summary> public  string Headurl {get; set;}  <summary>///Blog address///  </summary> public  string Blogurl {get; set;}  <summary>//Likes///  </summary> public  int Zannum {get; set;}  <summary>///read///  </summary> public  int Readnum {get; set;}  <summary>///comments////  </summary> public  int Commitenum {get; set;}  <summary>//creation time///  </summary> public  DateTime createtime {get; set;}}

Then, you need to create an interface iblogsreposity, and define a method for the following code:

Public interface Iblogsreposity {//<summary>///  Get blog Information//</summary>//  <param Name= "Ntask" ></param>//  <returns></returns>  task<ienumerable<moblog> > getblogs (int ntask); }

Note that the return type defined here is TASK<T>, and the main function is that async returns the blog information asynchronously and makes it easy to crawl different pages of data in parallel, so here is an int type parameter Ntask (representing the number of tasks) All right, let's take a look at the code in the Bokeyuan class that implements the interface specifically:

public class Bokeyuan:iblogsreposity {public async task<ienumerable<moblog>> getblogs (int ntask) {var   Blogs = new list<moblog> (); try {//Open Ntask task, read pre ntask page information task<ienumerable<moblog>>[] tasks = new TASK&LT;IENUMERABLE&LT;MOBLOG&G    t;>[ntask]; for (int i = 1; I <= tasks. Length;       i++) {Tasks[i-1] = await task.factory.startnew<task<ienumerable<moblog>>> ((page) = = {      Return Getblogsbypage (Convert.ToInt32 (page));    }, I);    }//30s waits for Task.waitall (Tasks, Timespan.fromseconds (30)); foreach (var item in tasks.) Where (b = b.iscompleted)) {blogs. AddRange (item.    Result); }} catch (Exception ex) {} return blogs.  OrderByDescending (b = b.createtime); }//<summary>///</summary>/<param name= "Npage" > Pages </param>///&LT;RETURNS&GT;&LT ;/returns> async task<ienumerable<moblog>> getblogsbypage (int npage) {var blogs = new list<moblog> (); try {var strblogs = string.    Empty; using (HttpClient client = new HttpClient ()) {strblogs = await client.    Getstringasync ("http://www.cnblogs.com/sitehome/p/" + npage); } if (string.    Isnullorwhitespace (Strblogs)) {return blogs;} var matches = regex.matches (Strblogs, "diggnum\" [^>]+> (? 

Code Analysis:

1. task<ienumerable<moblog>>[] tasks = new Task<ienumerable<moblog>>[ntask] As a container for parallel tasks;

2. Task.Factory.StartNew create the corresponding task

3. Task.waitall (Tasks, Timespan.fromseconds (30)), waiting for the container to expire after 30 seconds of task completion

4. Finally pass the item. Result task results are added to the collection, returning the data we need

Here to parse the blog content information with the regular expression, this way in the grasp of a certain content is very convenient; some friends in the group is a little disgusted, just contact with the time feel very bad write, so generally use more complex or other analytic way to obtain the desired content, The main point here is to share with these friends how convenient it is to get the data, it is necessary to learn and master the conventional usage, it is also a kind of kujinganlai experience bar haha;

All right, guys. Create a WEBAPI project named Stage.api, using the Get method interface in her auto-generated Valuescontroller file to invoke the blog crawl method implemented above, the code is as follows:

Get api/values public  async task<ienumerable<moblog>> Get (int task = 6)  {   task = task <= 0? 6:task;   Task = task > 50? 50:task;   Iblogsreposity _reposity = new Bokeyuan ();   return await _reposity. Getblogs (Task);  }

Here use iblogsreposity _reposity = new Bokeyuan (); To create and invoke a specific implementation class, here is a line to crawl the blog home page information address (do not tell Dudu): http://www.php.cn/:1001/api/values?task=6; let's imagine, If the Get method also needs to invoke other implementation of the interface iblogsreposity of the blog crawl class, then we need to manually new to create the corresponding object, if in addition to the ValuesController.cs file to invoke the blog data fetching, Other files need this to crawl the data business, then will not stop new, may have friends will say that a factory model how, good this is a feasible way, but there are other ways to deal with this problem, such as: IOC dependency Injection, so there is the following share content.

The use of»IOC frame Ninject

First of all, we need to use Ninject to download the installation package, it is important to note that the Ninject version is more, you need to choose the appropriate version of their webapi, I chose here:

Looks very old haha, but we can use on the line, installation may take some time, after all, is larger than the network may be the problem it? After installation, we create a custom class Ninjectresolverscope and implement Interface Idependencyscope, Idependencyscope corresponds to the class library is System.Web.Http.dll (note: Because the WEBAPI2 Project automatically generated when it may be checked Mvc,mvc frame also contains a idependencyscope, So we need to pay attention to the distinction of the next, okay, let's just look at the Ninjectresolverscope implementation code:

<summary>//parsing///</summary> public class Ninjectresolverscope:idependencyscope {  private Iresolu Tionroot Root;  Public Ninjectresolverscope () {} public  Ninjectresolverscope (iresolutionroot root)  {   this.root = root;  } Public  Object GetService (Type servicetype)  {   try   {    return root.} Tryget (servicetype);   }   catch (Exception ex)   {    return null;   }  }  Public ienumerable<object> getservices (Type servicetype)  {   try   {    return this.root.GetAll (servicetype);   }   catch (Exception ex)   {    return new list<object> ();   }  }  public void Dispose ()  {   var disposable = this.root as IDisposable;   if (disposable! = NULL)    disposable. Dispose ();   This.root = null;  } }

It is important to note that the GetService and getservices methods must be wrapped with try...catch (), tested and tested by multiple parties, which perform dependencies other than manual bind bindings, and perform several other instance objects that are not manually bound. Here we use try to avoid throwing the exception to the program (in fact, we can use code here to filter out a few instances of non-manual binding); Here's a brief example of the sequence of methods executed in this ninjectresolverscope: getservice= "getservices=" Dispose,getservice is used primarily to obtain an instance of a dependency injection object; Well, here we need a custom container class Ninjectresolvercontainer, which inherits from the above Ninjectresolverscope and implementation Idependencyresolver interface (In fact, careful friends can find this idependencyresolver also inherit Idependencyscope), the specific code is as follows:

public class Ninjectresolvercontainer:ninjectresolverscope, idependencyresolver {  private ikernel kernel;  public static Ninjectresolvercontainer current  {   get   {    var container = new Ninjectresolvercontainer () ;    Initializes the    container. Initing ();    Bind    container. Binding ();    return container;   }  }  <summary>  //initialization kernel  ///</summary> void initing ()  {   kernel = new Standardkernel ();  }  <summary>  ///bind//</summary> void binding ()  {   kernel. Bind<iblogsreposity> (). To<bokeyuan> ();  }  <summary>///Start execution//</summary>//  <returns></returns>  Public Idependencyscope BeginScope ()  {   return new Ninjectresolverscope (This.kernel.BeginBlock ());}  }

Here you can see Ikernel kernel = new Standardkernel (); This code, their references are derived from our installed Ninject package, by invoking the initialization of initing (), we need to bind in the binding () method manually we need to rely on injection of the instance, Ninject binding way There are many kinds of the format I used here is: kernel. bind< interface > (). to< Realization Class > (); It's so easy to implement dependency injection, and each time we need to add a different dependency, we only need to use the bind< interface in this binding (). to< Interface Implementation Class > () to bind successfully; Well, to verify the success of our test, we need to use this dependency in Apicontroller, where I use the constructor dependency injection:

Private readonly iblogsreposity _reposity public  valuescontroller (iblogsreposity reposity)  {   _reposity = reposity;  }  Get api/values public   async task<ienumerable<moblog>> Get (int task = 6)  {   task = task <= 0? 6:task;   Task = task > 50? 50:task;   return await _reposity. Getblogs (Task);  }

Code as shown above, we run the following program to see the effect:

This time the error "There is no default constructor"; The constructor that we just used is a parameter, and the custom inherited Apicontroller has a parameterless constructor, which is completely non-solvable based on the error message; Don't worry, it's only necessary to solve the problem Add the following code to the Register method in WebApiConfig.cs:

Ninject IOC CONFIG. Dependencyresolver = ninjectresolvercontainer.current;

This code means that the program executes the container Ninjectresolvercontainer created above so that it can execute to the IOC program I just wrote to enable dependency injection, and it's worth noting that config. Dependencyresolver is provided by WEBAPI, the MVC project also has the same provided dependencyresolver to us to use to do dependency resolution; Well, this time we're running the project to get results:

»IOC Framework Unity's use

First, install the NuGet package for unity and UNITY.WEBAPI, and here's my version:

We'll also create a custom container class Unityresolvercontainer to implement the interface Idependencyresolver (here, as in the above Ninject), and then stick to the specific method of using unity:

public class Unityresolvercontainer:idependencyresolver {private Iunitycontainer _container;  Public Unityresolvercontainer (Iunitycontainer container) {This._container = container; } public Idependencyscope BeginScope () {var scopecontainer = This._container.   Createchildcontainer ();  return new Unityresolvercontainer (Scopecontainer); }///<summary>///for the corresponding type of instance, note try...catch ... cannot be less//</summary>//<param name= "servicetype" ></param>//<returns></returns> Publi C Object GetService (Type servicetype) {try {//if (!this._container.    Isregistered (servicetype)) {return null;} Return This._container.   Resolve (servicetype);   } catch {return null; }} public ienumerable<object> getservices (Type servicetype) {try {return this._container.   ResolveAll (servicetype);   } catch {return new list<object> (); }} public void Dispose () {if (_container! = null) {This._container. DispOSE ();   This._container = null; }  } }

This is similar to the way you use Ninject, and it is important to note that we automatically add the following code to the WebApiConfig.cs when we install the Unity package:

Unity iocunityconfig.registercomponents ();

Then add the UnityConfig.cs file in the App_start folder at the same time, we open this file can see some auto-generated code, here we can register binding our dependencies, code such as:

public static class Unityconfig {public  static void Registercomponents ()  {   var container = new Unitycontaine R ();   Container. Registertype<iblogsreposity, bokeyuan> ();   var lifetimeoption = new ContainerControlledLifetimeManager ();   Container. Registerinstance<iblogsreposity> (New Bokeyuan (), lifetimeoption);   GlobalConfiguration.Configuration.DependencyResolver = new Unityresolvercontainer (container);  } }

Here are two ways of registering dependencies: container. Registertype<iblogsreposity, bokeyuan> (); and container. Registerinstance<iblogsreposity> (New Bokeyuan (), lifetimeoption); , of course, there are other extension methods here are not examples; the last sentence code: GlobalConfiguration.Configuration.DependencyResolver = new Unityresolvercontainer ( container); And our previous Ninject code, just changed a place and instanced way of writing, you can carefully contrast, in fact, the contents of UnityConfig.cs can be moved to WebApiConfig.cs, Unity Auto-separation should be to consider the code content chunking to manage it, OK again we use the custom Valuescontroller constructor to add dependencies:

public class Valuescontroller:apicontroller {  private readonly iblogsreposity _reposity;  Public Valuescontroller (iblogsreposity reposity)  {   _reposity = reposity;  }  Get api/values public   async task<ienumerable<moblog>> Get (int task = 6)  {   task = task <= 0? 6:task;   Task = task > 50? 50:task;   return await _reposity. Getblogs (Task);}  }

From the code point of view, there is no difference between ninject and unity in this way, so that we can develop the program when the two injection methods to switch freely, the most later I provide a use of this webapi to get data bound to the page effect:

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.