webapi aspnet 4架构

时间:2012-11-19 04:14:01

标签: asp.net-mvc-4 asp.net-web-api

我的项目使用Entity Framework 5 Code First,WebApi,ASPNET MVC 4,Repository和Unit of Work模式等。

我的架构如下:

  • POCOS的一个项目
  • 一个带有上下文,存储库,工作单元等的项目
  • 一个包含合同的项目(IRepository,IUnitOfWork等)
  • 一个WebApi项目,为模型的每个实体(GET,POST,PUT,DELETE)保存ApiControllers。

现在,如果我不想使用SPA(因为我现在没时间学习它),我想快点做一些事情,我该怎么办?一个新的ASPNET MVC 4项目,控制器继承自Controller而不是ApiController,那些控制器使用WebApi控制器?

喜欢这个吗?

public ActionResult Index()
{
    return View(WebApiProj.Uow.Houses.GetAll());
}

这似乎不太好,因为它应该创建一个Get指向另一个项目中的WebApi控制器。

我正在考虑这种架构,因为移动客户端,Web客户端和任何其他客户端都会调用相同的服务,这听起来不错。

有关此架构的任何建议吗?优点还是缺点?

2 个答案:

答案 0 :(得分:2)

我不确定你展示的是否可能? WebApiProj.Uow.Houses.GetAll()将Houses视为一个具有static GetAll函数的类。 Houses是一个需要根据请求实例化的实例类,可能/应该有构造函数注入问题来处理...... GetAll通常是一个实例方法。

鉴于您将拥有多个代码客户端,即WebApi控制器和MVC控制器,您应该考虑在项目中添加服务层。 http://martinfowler.com/eaaCatalog/serviceLayer.html

您的服务层可能采用单个类的形式(如果这是一个小型项目,但在需要时将其拆分),它将注入存储库和基础结构代码。您应该得到一系列CRUD和UseCase探测方法名称,这些名称包含存储库,工厂和工作单元类之间的编排逻辑。

public interface IMyServiceLayerClass
{
      IEnumerable<House> GetAllHouses();
      House SaveHouse(House house);
      IEnumerable<Windows> GetAllHouseWindows(int houseId);
      //etc
}

public class MyServiceLayerClass : IMyServiceLayerClass
{
     private readonly IRepository<House>  _houseRepository;
     private readonly IUnitOfWork  _unitOfWork;
     private readonly IRepositoryTypeB _repositoryTypeB; 

     Public MyServiceLayerClass(IUnitOfWork unitofwork, IRepository<House> houseRepository, IRepositoryTypeB repositoryTypeB)
     {
           //Populate the private readonly's
     }

     public IEnumerable<House> GetAllHouses()
     {
         return _houseRepository.GetAll();
     }

然后,您的两种类型的控制器可以接受Service类,并且具有非常精简的逻辑,只需转发到服务层。

public class HomeController : Controller
{
    private readonly IMyServiceLayerClass _myServiceLayerClass;

    public HomeController(IMyServiceLayerClass myServiceLayerClass)
    {
        _myServiceLayerClass= myServiceLayerClass;
    }

    public ViewResult Index()
    {
         return View(_myServiceLayerClass.GetAllHouses());
    }

Api相同:

public class HouseController : ApiController
{
    private readonly IMyServiceLayerClass _myServiceLayerClass;

    public HouseController (IMyServiceLayerClass myServiceLayerClass)
    {
        _myServiceLayerClass= myServiceLayerClass;
    }

    public IEnumerable<House> Get()
    {
         return _myServiceLayerClass.GetAllHouses();
    }

这将允许您在控制器之间重用相同的业务逻辑和编排,从而将逻辑从WebApi和Mvc应用程序中抽象出来。

此代码可以很容易地存在于定义合同的项目中,因为它仅依赖于接口。或者您也可以将其接口添加到合同中,然后创建另一个项目类Domain或Service,它可以保存服务类的实现。

我强烈建议您让控制器做他们最擅长的事情,让他们处理UI特定元素的委托,并将非UI特定逻辑重新分解为可重用的服务层。这将允许控制器的单元测试专注于测试正确的操作结果和状态代码等,并允许您的域逻辑独立测试。

答案 1 :(得分:1)

看看my answer for another architecture question on MVC。您的问题的关键是拥有一个应用程序或域层,MVC控制器和Web API控制器都可以使用它来访问业务模型(MVC中的M)。您不希望直接从MVC控制器调用Web API,因为它具有此处不需要的序列化和反序列化的开销。而是直接调用应用程序/域层。