1

I have an application with an ASP .Net MVC 5 front end and a Web Api 2 service layer and I would like to use dependency injection so the MVC 5 controllers only rely on abstractions for the Web Api 2 ones.

Since the Web Api controllers mostly use this kind of signature:

public IHttpActionResult SomeMethod(){ return Ok(); }

my first thought was that the interface should be:

IHttpActionResult SomeMethod();

Now I have a class library with the interfaces for the services but that means that this class library would need a reference to System.Web.Http in order to use the IHttpActionResult interface in the signatures.

I have two questions:

  1. Fist this feels out right wrong that this library has a reference to System.Web.Http, is there an alternative to this?
  2. If there isn't an alternative, when I try to add the reference I only get an older version of the library which does not have a definition for that interface, where can I get the correct version from?

Thank you.

2 Answers 2

1

I would shove the common logic into a common library with 'normal' inputs and outputs. The two transports (MVC and web api) can then call this library

Sign up to request clarification or add additional context in comments.

Comments

1

It really depends on what you are trying to achieve - aka how much abstraction you want to introduce.

If you wan't to move all the common business logic into a service for re-use from here, and potentially anywhere then yes you want to get rid of the System.Web.Http references.

Do this by having a clean interface/implimentation that simply return the result of the actions something like this:

public interface ICustomerService 
{
    BaseResponse DoSomething(BaseRequest request);
}

public abstract class BaseResponse 
{
    public bool IsSuccess { get; set; }
    public IList<string> Errors { get; set; }
}

/*
Note: BaseResponse & BaseRequest, follow the command pattern for passing information you would impliment concrete versions of these.
*/

I then allow the controllers for both Web & Api control how to use this BaseResponse to er...respond.

So maybe create a BaseController, and BaseApiController:

For example:

public abstract class BaseApiController : ApiController 
{
        protected HttpResponseMessage HandleResponse(BaseResponse response)
        {
            return
                !response.IsSuccess
                    ? Request.CreateErrorResponse(HttpStatusCode.BadRequest, response.Errors )
                    : Request.CreateResponse(HttpStatusCode.OK, response);
        }
}

And:

public abstract class BaseController : Controller
{
    protected ActionResult HandleResponse(BaseResponse response, string redirectToAction)
    {
        if (response.IsSuccess) 
            return RedirectToAction(redirectToAction);

        foreach (var error in response.Errors)
        {
            ModelState.AddModelError(string.Empty, error);
        }

        return View();
    }
}

Then in WebApi Controller:

public HttpResponseMessage DoAction(string param1)
    {
        return HandleResponse(_customerService.DoSomething(new DoActionRequest { Param1 = param1 }));
    }

And in the Web Controller

public ActionResult DoAction(ViewModel viewModel)
    {
        var response = _customerService.DoSomething(new DoActionRequest { Param1 = param1 });

        return HandleResponse(response, "Success");
    }

In this way all busienss logic is tucked away and resusable, and the ApiController and Controllers can respond in their own unique ways.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.