如何将业务层添加到 C# MVC 应用程序

Posted

技术标签:

【中文标题】如何将业务层添加到 C# MVC 应用程序【英文标题】:How to add a Business Layer to an C# MVC application 【发布时间】:2014-07-12 03:24:39 【问题描述】:

我在 Github 上有一个我正在尝试开发的项目,该项目展示了如何以实用的方式使用最佳实践。但是我对这些概念有疑问。当我这样做时,我会回到基础并尝试一个简单的例子。要查看该项目,请点击此链接:

https://github.com/franasm/Store.git

工作分支的 DI/IOC 完全正常工作。当我尝试添加一个简单的业务层时,发生了损坏的分支。所以我回到了基础。

我创建了一个沼泽标准的简单 MVC4 应用程序。 然后我添加了带有单个表的 EF5(上面项目中的产品表)。

我决定添加一个没有任何 DI/IOC 或任何花哨的东西的业务层。但是这个概念让我很困惑。

在这个例子中,我想做的就是创建一个扩展产品类的类,添加一个名为 TaxAmt 的属性,并在实例化该类时添加一个计算 TaxAmt 的方法。

我尝试了各种方法,但得到了各种错误。从堆栈溢出异常,到实例未设置异常。大多数情况下,该事物只是不显示值,因为 Product.Price 字段未初始化。

我也发现我的BL放错地方了:

我有我的模型, 然后是我的 BL, 然后是我的控制器。

这个小例子很好。但是因为我能得到的最接近工作示例的是创建由 EF 生成的现有类的部分类,所以当我将其拆分为使用 DI/IOC 时,BL 将位于接口的错误一侧,因为它将是模型类(部分类)的一部分。

我希望我的图层清晰分开,例如: EF 模型类, 接口, 回购, BL, 控制器, 视图模型, 意见。

因为 Repo 负责 crud 操作。 BL 应该以此为基础。在读取产品详细信息(其中一个是价格)后,BL 可以获取此信息,进行税收计算,然后控制器可以使用此信息。

我不确定我的想法是否正确。

在大多数情况下,我非常不同意 BL 应该是模型的一部分。但是,即使对于我上面描述的人为示例来说就是这种情况。我仍然无法让它工作。然而,我正在寻找一个解决方案,它着眼于继承模型类,扩展它,然后将它与 repo 一起使用。但这又让我陷入了困境。 crud 由 repo 层完成,它无法访问 BL,那么 BL 如何初始化以进行税收计算。我不是加倍对象,每个模型实例的 POCO,然后也是同一对象的 BL 实例。

我真的很困惑...

基本上,我没有包含代码,因为我实际上所做的只是创建一个简单的表、一个简单的 mvc 项目、添加 EF5 模型、将它们全部连接起来以执行 crud 操作并确保它正常工作。然后尝试按照描述添加 BL。 BL 文件夹中的单个类,要么被定义为模型的部分类(不理想),要么直接继承模型类(也不确定这是否很酷)。理想情况下,我希望能够使用 DI,将我的 repo 注入我的 BL,然后将我的 BL 注入我的控制器。

如果有人知道如何执行此操作,您能否通过提供分步说明(最好是一些示例代码)或解释如何执行此过程以及我为什么会这样来向我提供答案困惑。

提前感谢您的帮助。

【问题讨论】:

【参考方案1】:

因此,我见过的创建具有业务层和 EF 层的 MVC 应用程序的最佳方式是采用 3 层布局。

我们有数据项目,它可能是您的 EF 项目(也可能是 SSDT 或类似的东西),然后是“服务”层(实际上可能是 Web 服务,但也可能只是常规类输出 DLL)。我有时也称它为我的“代理”层。此处的类托管模型,并将模型从 EF 代码转换为这些模型。这是使用 LINQ 的示例:

public static BlogModel GetBlog(string ID)
    
        Blog b;
        using (Entities cm = new Entities())
        
            b = cm.Blogs.Where(blog => blog.ID == ID).FirstOrDefault();
        

        if (b != null)
            return GetBlog(b);

        return null;
    

所以这个方法将使用 EF 和 LINQ to SQL 从数据库中获取一个 Blog 对象。现在,把它变成模型:

public static BlogModel GetBlog(Blog blog)
    
        return new BlogModel()
        
            Title = blog.Title,
            Enabled = blog.Enabled
        ;
    

这当然也使用了一个带有字符串 Title 和 bool Enabled 的 BlogModel 对象。仅作为示例。

所以现在您的业务层中有两个方法可以返回一个模型。您现在可以像这样在控制器中调用它:

    [Route("/Blogs/id", RouteName = "Blogs")]
        public ActionResult ViewBlogs(string id)
        
            BlogModel m = BusinessNamespace.BlogClass.GetBlog(id);
            return View("Blogs", m);
        

现在,假设您有一个带有正确模型设置的 Blogs.cshtml 视图,您应该可以开始了。

希望对一些人有所帮助。

【讨论】:

也许我没有完全理解...中间的代码块我称之为模型。我会考虑我的存储库的第一个代码块。最后一个块是你所说的控制器。前两个让我感到困惑,因为不清楚哪个先出现,模型或回购。你在这里解释的方式,似乎回购是第一位的。如果是这样,那么它从哪里获得表的结构。是否有一个同样名称首先定义的 EF 类。在这种情况下,中间的代码块可能会变成 BL,但是如果有 3 个代码块都命名相同,就会变得混乱。 是的,这是使用 EF(您了解的比您自己认为的要多),并且出于某种原因(也许是小时),我认为这很清楚。我现在可以看到它不是。对此感到抱歉。

以上是关于如何将业务层添加到 C# MVC 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

如何将数据从表示层传递到业​​务逻辑层? (ASP.NET MVC 5)

用现有的数据和/或业务层替换 MVC 中的模型?

c# 中的解决方案架构,其中 winforms 和 asp.mvc 共享业务逻辑和数据访问 [关闭]

任何将单独的数据访问层(使用 EF)突出显示到业务逻辑层的示例 C# 项目

在 MVC 架构中将业务逻辑保留在哪里?

如何将 DatePicker 添加到我的 MVC3 C# 站点