更好地组织mvc中的数据库操作代码

时间:2014-03-23 00:49:21

标签: asp.net-mvc ninject

我是.net mvc的新手,这是我的情况,在mvc解决方案中,我有数据模态和重新定位,也有ioc容器,当来操作数据操作时,我应该把所有逻辑代码都放在控制器中?还是有更好的方法?

public ActionResult SomeOperate(Person person)
{

    var reposity = _kernel.Get<IReposity<Person>>();   

    //what about if there are many database operation logical based on my generic reposity,should I put them all here?

    return RedirectToAction("SomeWhere");

}

EDIT1 我的通用reposity已经支持基本的数据库操作,如添加,更新,删除,查询事务

2 个答案:

答案 0 :(得分:1)

默认情况下,控制器可以包含业务逻辑(并且可以)。但随着应用程序规模的扩大,您开始怀疑控制器是否应该负责包含业务逻辑。

在更先进的架构中,控制器仅作为“教练”,让玩家完成工作。换句话说,控制器只担心应该什么。因此名称为 controller

服务层

服务层只是为一个目的而创建的类的集合,用于封装业务层,将逻辑从控制器移开。

请参阅下面的示例,了解服务的基本实现。

<强>服务

public class ProductService
{
    private IProductRepository productRepository;

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

    public IEnumerable<Product> ListProducts()
    {
        return this.productRepository.ListProducts();
    }

    public void CreateProduct(Product productToCreate)
    {
        // Do validations here.

        // Do database operation.
        this.productRepository.Create(productToCreate);
    }
}

<强>控制器

// Controller

public class ProductController : Controller
{
    private ProductService productService;

    // If you are wondering how to instantiate this
    // controller, see the ninject tutorial
    // http://www.codeproject.com/Articles/412383/Dependency-Injection-in-asp-net-mvc4-and-webapi-us
    public ProductController(ProductService productService)
    {
        this.productService = productService;
    }


    public ActionResult Index()
    {
        IEnumerable<Product> products = this.productService.ListProducts();

        return View(products);
    }

    public ActionResult Create()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Create(Product productToCreate)
    {
        if(!ModelState.IsValid)
        {
            return View();
        }

        this.productService.Create(productToCreate);

        return RedirectToAction("Index");
    }

直接来自Microsoft的完整教程:http://www.asp.net/mvc/tutorials/older-versions/models-(data)/validating-with-a-service-layer-cs

更新

为何使用服务层

https://softwareengineering.stackexchange.com/questions/162399/how-essential-is-it-to-make-a-service-layer

每个型号/实体的服务

关于每个型号的服务数量,没有绝对的规则。大多数情况下,它可以扩展为一对一,有时一对多(每个模块的引用服务)

单个服务类中的数字例程取决于UI中的操作数,这意味着如果系统中的任何位置都没有删除按钮,则代码中的任何位置都不应该有删除方法。换句话说,CRUD只应在需要时应用。

每个模块的服务

有时,服务可以扩展到多个模型,因为有一项操作需要您更新多个模型。这有时被称为“每个模块的服务”,这是服务不代表模型而是代表操作。

RetireService
 - RetireEmployee(User user)

MailingService
 - SendWeeklyMails()

服务和界面

大多数情况下,服务层不需要接口。他们唯一一次出于以下原因:

  • 大型团队(5人或以上)
  • 大型系统
  • 重度测试驱动开发。

此链接在此主题上有很多内容: https://softwareengineering.stackexchange.com/questions/159813/do-i-need-to-use-an-interface-when-only-one-class-will-ever-implement-it

答案 1 :(得分:0)

单一责任原则表明您应该为每个班级确定一项责任,并避免将逻辑纳入不属于该责任的班级。

如果这只是学习技术或小项目的练习,那么您可能会安全地将大部分实体操作和业务逻辑放在各个控制器操作中。如果这个项目可能会增长,并且需要随着时间的推移需要由不同的人进行维护,那么您最好不要立即定义N层架构。

如何做到这一点在某种程度上取决于个人偏好和项目的性质,但一种流行的方法是创建一个服务&#34;或者&#34;经理&#34;所有业务逻辑所在的层。然后,各种控制器操作会调用该层上的操作,将它们转换为ViewModel对象,并将它们传递给视图。在这种体系结构中,控制器最终开始非常轻量级,主要集中在将请求转换为服务调用并组合视图需要呈现的数据。

许多人认为ORM(例如实体框架)代表了数据访问层,&#34;并且他们不需要在服务层之外创建额外的层。其他人创建个性化的类来将查询和命令保存到Entity Framework,而Service层则利用这些不同的其他类。