我是ASP.NET MVC的新手。我对项目的架构感到很困惑。让我向你们解释一下我的困惑:
在我的项目中,我有三个部分,我们都知道。它们是:控制器,模型和视图。
控制器驻留在Controllers
文件夹中,视图进入Views
文件夹,模型位于Models
文件夹内。
众所周知,有两种类型的模型:数据模型和商业模型。数据模型具有要在项目中使用的所有数据类型,业务模型确实具有与项目相关的其他逻辑。除此之外,应用程序的数据层将与数据库进行通信。
我将为此数据层创建一个类库项目,该项目将与数据库通信。此外,我的MVC项目的Models
文件夹将只有数据模型,我也将为业务模型类创建一个不同的库。
现在我面临的问题是:
假设我的MVC项目名称为MVCProj
,数据层项目名称为DataProj
,业务层项目名称为BusinessProj
。
如果我在Models
的{{1}}文件夹中定义数据类型,我必须在MVCProj
和BusinessProj
项目中包含其引用。此外,我必须在DataProj
中使用BusinesProj
个类。因此,我必须在MVCProj
中添加BusinessProj
的引用,这会导致循环依赖。
我不确定我所设想的架构是否正确。请帮我解决一下。
答案 0 :(得分:6)
阿森的答案已经解释得很好,但我只是想发表自己的经历(而且评论的时间太长了。)
您将业务逻辑与DataAcess分离的想法很好。我工作的大多数项目都是以类似的方式组织的。
我要做的是:
1 - 为DataAcess创建项目:MVCProj.DataAcess
2 - 仅创建另一个项目以包含您的数据库实体:MVCProj.Entities
3 - 在MVCProj.Entities
项目中添加MVCProj.DataAcess
的引用
4 - 为您的业务层创建项目:MVCProj.Business
:
5 - 在MVCProj.Entities
项目中添加MVCProj.DataAcess
和MVCProj.Business
的引用(我假设业务层将调用数据库)
6 - 为您的MVC项目添加MVCProj.Entities
和MVCProj.Business
的引用。
看到逻辑?每一层都负责“做它的工作”。现在MVC控制器可以调用业务,它会调用数据库来保存记录。所有项目共享相同的实体。
MVC项目中的“Models”文件夹只是团队提供的一个示例。在Web中的大多数示例中,您会看到人们直接在控制器内调用数据库(主要使用实体框架)。这有效,但从长远来看维护起来非常糟糕。
大多数人做的另一件事是:您通常不希望在控制器中返回数据库实体。也许它们包含的内容超出了您的需求等等。在这种情况下,您可以创建所谓的ViewModel。可以想象一个类似于Entity类副本的ViewModel,但只能看到与View相关的字段。 ViewModel特定于MVC项目,因此它们将保留在MVC项目内的文件夹中。您可以将其命名为Models或ViewModels。
进展不多,但是通过上面展示的项目分离,你可以明确地寻找一个依赖注入框架来为你处理所有类的实例创建。 :)
注意:这是隐含的,但除了MVC之外的所有项目都只是普通的旧类库。
希望这有助于澄清您的想法。
答案 1 :(得分:1)
架构中没有银弹,所有这些都不是必须的,但取决于项目......
应用程序中的图层数量很大程度上取决于要求。
另一方面,附加层将关注点(例如:从DataAccess到Business Logic)分开,每个级别增加了工作量,降低了性能
关于你的问题,没关系,当一层依赖于另一层时,第三层取决于第一层是不正确的......
在你的情况下你选择3级,理想情况下它应该是这样的
DataAccess,其数据类位于单独的项目中
BusinessLogic,另一个项目,它调用数据访问,并将结果转换为其数据类
最后在模型参考上仅限BusinessLogic
答案 2 :(得分:1)
我做了一个写作,我认为我帮助你的一些困惑:Entities are not Models。
TL; DR这里混淆的主要原因似乎是您认为您需要MVC项目的Models
文件夹中的“数据模型”(实体)。这在两个方面是不正确的。首先,Models
文件夹是没有意义的。您可以重命名,删除它,等等。它根本不会影响您的应用程序。其次,正如我提到的细节,实体不是模型。它们应该只是表结构的表示,以便为您的ORM(实体框架)提供一些填充从数据库检索的数据的位置。
那就是说,典型的方法如下:
在您的MVC项目中,您的Model
文件夹基本上可以消失,或者您可以将其用于存储视图模型。但是,实际上为这些文件夹创建一个ViewModels
文件夹是很常见的。但是,这完全取决于你。
最后一点说明。 “业务层”也可以由多个不同的类库组成。例如,在我的组织中,我们有一个专门用于处理POS系统的库,一个用于连接我们用于电子邮件列表的API的库,一个用于处理Elasticsearch的库等。我们的Web项目只包含他们需要的任何库利用。