我有一个ASP .Net MVC 5前端和Web Api 2服务层的应用程序,我想使用依赖注入,因此MVC 5控制器只依赖于Web Api 2的抽象。
由于Web Api控制器大多使用这种签名:
public IHttpActionResult SomeMethod(){ return Ok(); }
我的第一个想法是界面应该是:
IHttpActionResult SomeMethod();
现在我有一个带有服务接口的类库,但这意味着这个类库需要引用System.Web.Http才能在签名中使用IHttpActionResult接口。
我有两个问题:
谢谢。
答案 0 :(得分:1)
我会将常用逻辑推入具有“正常”输入和输出的公共库中。然后两个传输(MVC和web api)可以调用此库
答案 1 :(得分:1)
这实际上取决于你想要实现的目标 - 也就是你要引入多少抽象。
如果您不想将所有常见业务逻辑移动到服务中以便从此处重复使用,并且可能在任何地方,那么您希望摆脱System.Web.Http
引用。
通过使用干净的界面/ implimentation来简单地返回这样的操作结果:
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.
*/
然后我允许控制器用于Web和&amp; Api控制如何使用此BaseResponse来响应...
因此,可以创建一个BaseController
和BaseApiController
:
例如:
public abstract class BaseApiController : ApiController
{
protected HttpResponseMessage HandleResponse(BaseResponse response)
{
return
!response.IsSuccess
? Request.CreateErrorResponse(HttpStatusCode.BadRequest, response.Errors )
: Request.CreateResponse(HttpStatusCode.OK, response);
}
}
和
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();
}
}
然后在WebApi Controller:
public HttpResponseMessage DoAction(string param1)
{
return HandleResponse(_customerService.DoSomething(new DoActionRequest { Param1 = param1 }));
}
并在Web控制器中
public ActionResult DoAction(ViewModel viewModel)
{
var response = _customerService.DoSomething(new DoActionRequest { Param1 = param1 });
return HandleResponse(response, "Success");
}
通过这种方式,所有业务逻辑都隐藏起来并可重复使用,ApiController和控制器可以以自己独特的方式响应。