1

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

我的架构如下:

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

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

像这样?

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

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

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

关于这个架构有什么建议吗?优点还是缺点?

4

2 回答 2

2

我不确定您展示的内容是否可行?WebApiProj.Uow.Houses.GetAll() 将 Houses 视为一个带有staticGetAll 函数的类。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 特定逻辑重构为可重用的服务层。这将允许控制器的单元测试专注于测试正确的操作结果和状态代码等,并允许独立测试您的域逻辑。

于 2012-11-19T10:09:37.523 回答
1

看看我对 MVC 上另一个架构问题的回答。您问题的关键是拥有 MVC 控制器和 Web API 控制器都可以用来访问业务模型的应用程序或域层(MVC 中的 M)。您不想直接从 MVC 控制器调用 Web API,因为它具有此处不需要的序列化和反序列化开销。而是直接调用应用程序/域层。

于 2012-11-19T14:25:52.683 回答