繁体   English   中英

asp.net mvc分层应用程序,我理解正确吗?

[英]asp.net mvc layered application, am I understanding it right?

我已经阅读了很多可以在Internet上找到的asp.net mvc分层应用程序。 现在,该运用我所学的知识了。 请告诉我我是否做对了。 一个示例代码会很棒:D

这只是一个简单的分层应用程序。 开始,

<Company>.Data
        -- DataAccess (contains repo, interfaces and dbcontext)
        -- Mappings (mapping to models using fluent api)
        -- Migrations (schema migration)
        -- Filters (pipe and filter)
        - Product.cs
        - Customer.cs
        - Order.cs
<Company>.Service (consumes the interfaces and implementation)
        - ProductService.cs
        - CustomerService.cs
        - OrderService.cs
<Company>.Tests
<Company>.Web (ASP.NET MVC, have reference to Ninject, including ViewModels)

我想知道在<Company>.Service层中(例如,如果这应该是放置业务逻辑的地方)。

public class ProductService : IProductRepository
{
  public IQueryable<Product> GetProductByCustomer(int id)
  {
    // Some logic; Get all the products bought by the customer
  }
}

然后在我的Controller

public class CustomerController : Controller
{
  private readonly ICustomerRepository _customerRepo;
  private readonly IProductRepository _productRepo;

  public CustomerControll(ICustomerRepository customerRepo,
           IProductRepository productRepo)
  {
    _customerRepo = customerRepo;
    _productRepo = productRepo;
  }

  public ActionResult Index(int id)
  {
    var customerProducts = _productRepo.GetProductByCustomer(id);
    return View(customerProducts.ToList());
  }
}

请让我知道我是否需要改进或需要增加一些地方。 我只想从简单开始,然后继续学习。

注意:为简洁起见,我删除了一些代码。

非常感谢您的帮助。 谢谢!

你可以看看这个回购

https://github.com/MarlabsInc/SocialGoal

它包含一个使用ASP.NET MVC,EF,服务层,存储库模式,工作单元模式等实现最佳实践的示例项目。

我将更改您的ProductService ,使其包含使用合成而不是继承的存储库。 还是...反正看起来很像一个存储库,也许您打算将其称为ProductRepository 在这种情况下,您可能仍然需要ProductService来保存您的业务逻辑。

编辑

例如:

public class ProductService : IProductRepository
{
    public IQueryable<Product> GetProductByCustomer(int id)
    {
        // Some logic; Get all the products bought by the customer
    }
}

会成为:

public class ProductRepository : IProductRepository
{
    public IQueryable<Product> GetProductByCustomer(int customerId)
    {
        // Some logic; Get all the products bought by the customer
    }
}

在应用程序/服务层中,您将具有某种面向业务的功能:

public class ProductService
{
    private readonly IProductRepository productRepository;

    public ProductService(IProductRepository productRepository)
    {
        this.productRepository = productRepository;
    }

    public IEnumerable<Product> GetCurrentProductsOnOrderForCustomer(int customerId)
    {
        // etc.
    }
}

进一步编辑

通常,在分层体系结构中,您只会与您下面的直接层对话(尽管存在可以与您下面的任何层对话的体系结构,但它可能是您想要的层)。 您典型的分层应用程序将布局为UI/Presentation Layer -> Application/Service Layer -> Data Layer 您的Controllers通常位于UI Layer ,通常会引用Application/Service Layer ,像ProductService这样的东西将存在于其中。

为什么在控制器中调用存储库? 最好在服务中调用存储库接口,并在控制器中调用服务接口:

public class ProductService : IProductRepository
{
    private readonly IProductRepository _productRepository;

    public ProductService(IProductRepository productRepository) 
    {
        _productRepository=productRepository;
    }

    public IQueryable<Product> GetProductByCustomer(int id)
    {
        // Some logic; Get all the products bought by the customer
    }
}

然后在您的控制器中:

public class CustomerController : Controller
{
  private readonly IProductService _productService ;

  public CustomerControll(IProductService productService)
  {
    _productService = productService;
  }

  public ActionResult Index(int id)
  {
    //call service here
  }
}

如果您具有服务层,并且应该在域层而不是服务层或其他层中解决所有业务逻辑,则在控制器中调用存储库不是一个好习惯。

您的方向正确,但我建议您进行一些更改。 由于您的<Company.Data>具有用于MappingMigration文件夹...我想您应该为您的模型Product, Customer, Order命名一个文件夹Product, Customer, Order并将其命名为Model ,或者您可以将它们放置在其他项目中,并将其命名为<Company.Model> 。模型<Company.Model>

我认为您需要明确定义和理解服务的含义。 (a)它可能是您的应用程序的主要入口点,其他客户端(WebForms,MVC或任何表示框架)都将与之交互。 (b)您可以将服务称为域服务,该域服务定义了应用程序的业务规则/逻辑。

如果为(b),它将与您的存储库(用于处理从数据存储中检索数据)进行交互并包含业务规则。 例如

ProductRepository : IProductRepository 
{
    public IEnumerable<Product> FindAll()
    {
        ....
    }
}


ProductService
{
    public void ProductService(IProductRepository productRepository)
    {
          _repository = productRepository;
    }

    //Business rules follows
}

如果是(a),则可以根据您的目的以不同的方式实现,并将与您的域服务进行通信。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM