C# Design Patterns – Using the Request Manager Pattern

cdesign-patterns

I have observed in lot many C# example where in following pattern is being followed but i am not sure how this will going to help us in long run

Typical approach i have seen is

  1. create a interface
  2. implement interface
  3. create a manager
  4. call manager

it would be really nice if anyone can tell me how this approach will going to help in real world senario

interface IRestService for various web requests

public interface IRestService
    {
        Task<List<TodoItem>> RefreshDataAsync ();

        Task SaveTodoItemAsync (TodoItem item, bool isNewItem);

        Task DeleteTodoItemAsync (string id);
    }

Code that implements IRestService interface

public class RestService : IRestService
{
    HttpClient client;

    public List<TodoItem> Items { get; private set; }

    public RestService ()
    {
        var authData = string.Format("{0}:{1}", Constants.Username, Constants.Password);
        var authHeaderValue = Convert.ToBase64String(Encoding.UTF8.GetBytes(authData));

        client = new HttpClient ();
        client.MaxResponseContentBufferSize = 256000;
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authHeaderValue);
    }

    public async Task<List<TodoItem>> RefreshDataAsync ()
    {


    }

    public async Task SaveTodoItemAsync (TodoItem item, bool isNewItem = false)
    {

    }

    public async Task DeleteTodoItemAsync (string id)
    {

    }
}

Manager that calls the implemented methods

public class TodoItemManager
{
    IRestService restService;

    public TodoItemManager (IRestService service)
    {
        restService = service;
    }

    public Task<List<TodoItem>> GetTasksAsync ()
    {
        return restService.RefreshDataAsync (); 
    }

    public Task SaveTaskAsync (TodoItem item, bool isNewItem = false)
    {
        return restService.SaveTodoItemAsync (item, isNewItem);
    }

    public Task DeleteTaskAsync (TodoItem item)
    {
        return restService.DeleteTodoItemAsync (item.ID);
    }
}

to execute request

TodoManager = new TodoItemManager (new RestService ()); 
TodoManager.GetTasksAsync ();

few questions are running in my mind

  1. why we need a manager why can not we just use RestService
  2. if some day i need to develop one module to fetch contact related data from server then do i need to add methods in IRestServie to addContact() , deleteContact() , getContact()

Best Answer

Why we need a manager?

The manager represents the business logic that surrounds calling a rest service. Your example was a little to simple to see why a manager can be useful. Consider the use case where you need to deal with multiple REST services. But this is where you can handle pre-validation of data, do a follow-on call if addContact succeeds or fails, etc.

Why not use RestService Directly?

Testing. It makes testing your business logic (manager) separately from your rest service.

Versioning. It makes replacing the implementation of your RestService easier when the implementation needs to change due to versioning constraints.

Containment. The primary reason is to contain your business logic separately from your presentation logic. It also minimizes the impact if the new version of a RestService causes some extra steps that you have to maintain in code. By keeping one interface you have control over the same (your manager) you can contain the changes required by a change in an interface you don't really have control over (rest service).

Fetching new data from a new service

IRestService is a bad name for this reason. You would have separate interfaces for each REST service you needed to contact. For example, you would have a ITodoRestService and a IContactRestService or something like that. If your TodoManager needed to use both (i.e. associating todo items with a contact), it would have a reference to both. Which then leads you back to why we need a manager in the first place.

Related Topic