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

时间:2014-06-24 06:42:42

标签: c# asp.net-mvc asp.net-mvc-4 architecture

我已经阅读了很多可以在互联网上找到的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());
  }
}

如果我需要改进或需要添加的某些方面,请告诉我。我只是想开始简单,然后我会爬上去。

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

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

4 个答案:

答案 0 :(得分:3)

你可以看一下这个回购

https://github.com/MarlabsInc/SocialGoal

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

答案 1 :(得分:1)

我会更改您的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 - &gt;布局。 Application/Service Layer - &gt; Data Layer。您的Controllers将出现在UI Layer中,通常会引用Application/Service LayerProductService之类的内容会存在。{/ p>

答案 2 :(得分:1)

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

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
  }
}
如果你有服务层,那么在控制器中调用存储库并不是一个好习惯,所有业务逻辑都应该在不在服务层或其他层的域层中解决。

答案 3 :(得分:1)

你正朝着正确的方向前进,但我会推荐一些改变。由于您的<Company.Data>包含MappingMigration的文件夹...我认为您应该为模型Product, Customer, Order创建一个文件夹并将其命名为Model,或者您可以将它们放在不同的项目中,并将其命名为<Company.Model>

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

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

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


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

    //Business rules follows
}

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