Dependency Injection

In most real-world projects, we do not instantiate any objects using the new instance in any of the Controllers, the reason being that we don't want to have tight coupling between the dependent components (between the Controller and the repository). Instead, we pass an interface to the Controller, and the Dependency Injection container (such as Unity) will create an object for us when it is needed for the Controller. This design pattern is commonly referred to as Inversion of Control.

Let's say that a class by the name of ClassA uses another class, ClassB. In this case, it is enough for ClassA to know about the behavior, methods, and properties of ClassB, and it doesn't need the internal implementation details of ClassB. So, we can abstract ClassB and make an interface out of the class, and then have that interface as the parameter instead of the concrete class. The advantage of this approach is that we can pass any class at runtime as long as it implements a commonly agreed contract (interface).

In ASP.NET 5 (including ASP.NET Core and Web API), we have inbuilt support for Dependency Injection. In the ConfigureServices method, we have added the line (highlighted in bold) that performs the Dependency Injection. We instruct the inbuilt Dependency Injection container to create the EmployeeRepository class wherever we are referring to the IEmployeeRepository interface and we also instruct it to be a singleton; meaning that the same object (which is to be created by the Dependency Injection container) is to be shared for the entire lifecycle of the application:

public void ConfigureServices(IServiceCollection services)
{
  // Add framework services.
  services.AddApplicationInsightsTelemetry(Configuration);
  services.AddMvc();
  services.AddSingleton<IEmployeeRepository, EmployeeRepository>();

}

In the preceding code, we have used the Singleton pattern for the Dependency Injection, which creates services only the first time they are requested. There are other types of lifetime services such as Transient and Scoped. Transient lifetime services are created each time they are requested and Scoped lifetime services are created once per request. The following are code snippets created when you use such lifetimes:

services.AddTransient
  <IEmployeeRepository, EmployeeRepository>();


services.AddScoped  <
IEmployeeRepository, EmployeeRepository>();

Now it's time to get into the meat of the action creating the API controller. Right-click on the Controllers folder and select Add | New Item. Then select Web API Controller Class from the list, as shown in the following screenshot. Name your Controller, and click the Add button:

Dependency Injection

Remove the generated code in the Controller and add the following constructor:

public EmployeeController(IEmployeeRepository employeesRepo)
{
  employeeRepository = employeesRepo;
}
private IEmployeeRepository employeeRepository {get; set;}

In the preceding constructor, we are injecting the dependency. At the time of calling this constructor, the EmployeeRepository object will be created.

Let us implement a couple of GET methods—the first one will return all the employees' details and the second GET method will return the employee based on the passed employee ID:

public IEnumerable<Employee> GetAll()
{
  return employeeRepository.GetAllEmployees();
}

[HttpGet("{id}",Name ="GetEmployee")]
public IActionResult GetById(int id)
{
  var employee = employeeRepository.GetEmployee(id);
  if(employee == null)
  {
  return NotFound();
  }
  return new ObjectResult(employee);
}

Let us call these HTTP methods from Fiddler.

Run the solution, open the Fiddler application, and click on the Composer tab.

Select the HTTP method (we have chosen the GET method as we have a GET API method) and enter the URL http://localhost:49933/api/employee .

Please note that when I run my application, it runs on port 49933; the port number will be different in your case, so construct your URL accordingly.

Once you enter the URL and the method is selected, click the Execute button as shown in the following screenshot:

Dependency Injection

Once you click the Execute button, an HTTP session will be created, and the request will be fired.

Click on the session on the left-hand side pane (as shown in the following screenshot) and select the Inspectors tab in the right-hand side pane. You can view the result in the JSON tab in the bottom right-hand side pane:

Dependency Injection

Let us fire another HTTP request to get a particular employee's information, say the employee whose ID is 2. We would construct the URL by appending the ID  http://localhost:49933/api/employee/2  as following:

Dependency Injection

Select the recently created HTTP session and click on it:

You can see the result in JSON format in the right-hand side pane.

Now, we are going to add Create, Update, and Delete operations to our service. To start with, we are going to provide the Create functionality to add employees' to our service:

[HttpPost]
public IActionResult Add([FromBody] Employee emp)
{
  if (emp == null)
  {
    return BadRequest();
  }
  employeeRepository.AddEmployee(emp);
  return CreatedAtRoute("GetEmployee", new { id = emp.Id }, emp);
}

The following points should be considered when following the preceding Add method:

  1. We are passing the Employee object as a parameter. We are instructing the Add method to take that object from the body of the request by specifying a [FromBody] attribute:
    • If no employee object is passed, we would be returning the bad request to the calling client
    • If it is not null, we would be calling the repository method to add the employee to our list (in the real world, we would be adding it to the database)
  2. Once we have added the employee, we are returning the 201 status code (as per the HTTP standards) when a new resource is created.

Open the Fiddler application and follow these steps to add the employee:

  1. Select the HTTP method as POST and enter the URL http://localhost:54504/api/employee/.
  2. You need to specify the content type as application/json in the request header. Please see the following screenshot, where we have added Content-Type: application/json to the request header.
  3. As mentioned in the code, we have to pass the employee object in the form of JSON in the body of the request. In the following request, we have formed a JSON that contains the properties of the Employee object with the values in the brackets { "FirstName" : "James", "LastName" : "Anderson","Department" : "IT"}:

    Dependency Injection

Once you have composed the request, you can click the Execute button to fire the request. This will return the 201 HTTP status code, which is the standard HTTP response for creating a new resource:

Dependency Injection

As soon as we have created the resource in the server, we are redirecting the response to get the newly created resource. This occurs when we call the CreatedAtRoute method with the newly created employee ID passed as a parameter.

Click on the session on the left-hand side and select the Inspector tab in the right-hand side pane. Now you can see the response of the request. The response contains the Employee object which was newly created in the server. We have to note that the ID of the Employee object is generated at the server, and is available in the following response. In this case, the ID generated for the employee is 1771082655:

Dependency Injection

In the bottom right-hand side panel in the preceding Fiddler window, we can see the complete JSON response of the newly created resource.

Now we are going to add a Web API method to update the resource. The method for updating the resource is very similar to that used to create the resource, with only a few differences. When we created the resource, we used the HTTP POST method, whereas when we updated the resource, we used the HTTP PUT method.

If the passed employee ID could not be found in the repository, we return a 404 error response, the HTTP standard error response for a resource that has not been found.

The following is the Web API controller method code for updating the resource:

[HttpPut]
public IActionResult Update([FromBody] Employee emp)
{
  if( emp == null)
  {
    return BadRequest();
  }
  Employee employee = employeeRepository.GetEmployee(emp.Id);
  if(employee == null)
  {
    return NotFound();
  }
  employeeRepository.UpdateEmployee(emp);
  return new NoContentResult();
}

The following is the repository layer code for updating the employee:

public void UpdateEmployee(Employee emp)
{
  Employee employee = employees.Where(e => e.Id == emp.Id).FirstOrDefault();
  if (employee != null)
  {
    employee.Department = emp.Department;
    employee.FirstName = emp.FirstName;
    employee.LastName = emp.LastName;
  }
}

Open the Fiddler application, and compose a request of HTTP PUT. As we are going to pass the Employee object in the body of the request, we need to mention the content type as application/json. In the body of the request, we need to supply the Employee object in JSON format, as shown in the following screenshot:

Dependency Injection

When you click the Execute button, the HTTP PUT request will be fired and our Web API method will get called. Once it succeeds, the HTTP 204 response will be returned:

Dependency Injection

Delete method

The HTTP DELETE method should be used when deleting a resource. There is no need to pass anything in the body of the request.

The Web API method for deleting a resource

The Delete Web API method has a void return type, which will return an HTTP 200 response:

[HttpDelete("{id}")]
public void Delete(int id)
{
  employeeRepository.RemoveEmployee(id);
}

Web Repository layer code for deleting the employee data

In the following repository layer method, we are removing the employee (whose ID matches with that of the parameter passed) from the internal list of employees. But in the real world, we would be interacting with the database to delete that particular employee. Consider the following code:

public Employee RemoveEmployee(int id)
{
  Employee employee = employees.Where(emp => emp.Id ==   id).FirstOrDefault();
  if(employee != null)
  {
    employees.Remove(employee);
  }
  return employee;
}

Open the Fiddler application, select the DELETE HTTP method, pass the URL with the parameter, and click on the Execute button. Please note that we are not passing the content type in the request header as we are not passing any employee object in the body of the request:

Web Repository layer code for deleting the employee data

As we are returning void, the Web API DELETE method returns an HTTP 200 status, as you can see in the left-hand side pane of the Fiddler application:

Web Repository layer code for deleting the employee data

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset