繁体   English   中英

需要有关ASP.NET MVC 3体系结构的一些指南

[英]Some guidance on ASP.NET MVC 3 architecture required

我是一位经验丰富的.NET开发人员,主要从事Web表单的开发。 我熟悉MVC,但尚未在商业上使用过。 我目前正在这方面进行一些自我教育,但对建筑学的观点分歧感到有些困惑,让我以没有正确或错误答案为前提的这个问题作为前缀,而我只是在寻求什么。一个优雅的解决方案。

首先,我不会使用实体框架或任何类型的ORM,我想直接实现自己的业务对象和数据访问代码(使用ADO,SPROCS等)以确保它们是最佳的,这是个人喜好。 这是我在努力寻找一致信息的地方,因为看起来大多数信息与LINQ to SQL或实体框架的使用有关。

我的应用程序由以下项目构成:

  • Web(MVC 3 Web应用程序)
  • 模型(类库)

只有两个项目,因为我在解决问题上存在问题。 这是我问题的根源。 我的模型类库包含…

  • 具有字段和属性的经典业务对象
  • 每个业务对象的存储库类,其中包含数据访问代码(ADO.NET直接SqlDataReaders等)
  • 每个存储库类的接口

我遇到的问题是所有这些层之间的依赖关系。 感觉根本不对!

1.业务对象应包含实现业务逻辑的方法,因此,除了字段和属性外,还有实现所需逻辑的方法吗?

2.存储库类执行数据访问代码,但知道业务对象,这又感觉不对,数据访问代码应位于其自己的类库中,而对对象一无所知?

3.控制器(在Web层中)利用存储库接口,但是为什么呢? 它们不应该包含业务逻辑,“模型”或业务对象应该吗? 控制器当然不应该包含业务逻辑,所以这又是不对的。 我不希望存储库中的业务逻辑进入数据库。

我正在努力为应用程序找到一个优雅的体系结构,只是如何实现自己的对象,我自己的数据访问代码以及确保应用程序松散耦合的基本概述。 有人可以给我任何指导吗?

我建议对您的解决方案结构进行一些更改。

例如,项目的结构可以如下:

核心图书馆

这将是简单的POCO,代表您的域数据和任何服务的接口。 这里没有业务逻辑。 只是简单的属性。

例如。

公共类User {public int UserId {get; 组; } public string Name {get; 组; }}

- Core
      \Entities <-- Poco's
      \Services <-- Interfaces for services

服务

这就是您包含业务逻辑的地方。 用户如何验证? 我们如何计算何时应该自动归档订单? 通常,我在这里不做任何数据库工作。

资料库

这是您执行基本数据库工作的地方。 您说您没有使用L2S或EF等。没有问题。 我会认真考虑使用Micro-ORM,例如DapperMassive

测验

您正在进行单元和集成测试,对吗? 我建议将xUnit或nUnit用于测试框架。

Web应用程序

这是MVC3应用程序。 我建议对您的依赖注入使用StructureMap (您正在使用IoC / DI,对吗?)

您可能首先想到->这么多项目,对吗? 好吧,很容易将其分为两个项目。

  1. Web应用程序
  2. 测试项目

Web应用程序项目中的核心库,服务,存储库都作为文件夹存在。

尝试不要过度设计Visual Studio解决方案。 大多数人认为他们需要大量的项目和大量的抽象工作,..因为那是他们认为其他人都在做的事,这是正确的。 好吧,这个思路是在2000年代初期。2012年-自那时以来,许多神志发生了变化。

尝试使用DI / IoJ,使用NuGet将这些库下载到您的解决方案中,使用Micro-OR / M进行数据访问和测试项目。

一些项目要签出,关于:如何布置:

  1. JabbR.net
  2. RavenOverflow
  1. 也许,如果模型需要的话。 大多数模型是具有公共属性的简单dto。 但是您可以轻松地封装其中的一些内容。

  2. 不完全是。 存储库是业务对象的集合。 它可以从数据库创建这些对象的实例。

  3. 控制器是控制服务器上发生的事情的入口点。 读取将把存储库中的数据加载到视图模型中,并将视图模型推入视图中。 写入将从存储库加载数据,更新域并保存更改。 然后重定向到读取控制器操作。

最重要的是。 不要过度考虑架构。 这种事情发生得太多了。 开发人员想要干净的代码,实际上会使维护起来更复杂,而不是更简单。

无论您使用的是数据库还是ORM都无关紧要,存储库中的功能相同。

我认为从小做起是好的,然后随着需求的增长,您开始扩大视野并根据需要将各层分开。 如果您有2个模型,1个视图和一个表在数据库中进行查询和更新,为什么要将您的工作分为20个项目。

从小处着手,让“需求”驱动设计。 如果您需要读取/写入数据库中的许多表,现在可能是时候开始使用存储库模式了。 您发现您现在至少需要10个或更多个不同的模型,现在可能是时候实现一个包含DTO /模型的库并将其从Web应用程序中删除的时候了。

例如,如果您需要编写单元测试或执行TDD,那么您会发现能够立即模拟存储库,业务和服务层会派上用场。

为了便于讨论,我看到了与以下项目相似的项目(但大多数项目不需要这种分离程度):

  • 网络项目; 使用服务库和DTO库
  • 服务库; 消耗业务层库和dto库
  • 业务层库; 消耗存储库库,实体库和dto库
  • 存储库; 消费实体库
  • 实体库
  • dto库

其中大多数甚至进一步分解为单独的库,其中一个包含接口,另一个包含实现,依此类推。 我从事过的一些项目有50多个库,即使不是全部,也可以将大多数库分开,但这总是基于需求。

上面示例的思想是使Web应用程序仅处理将DTO传递到服务调用并从服务调用接收DTO的情况。

您通常可以将DTO用作模型,但是有时如果您需要基于多个DTO的平面模型,则可以创建自己的视图模型作为包装器以平整多个DTO。

该服务将通过驻留在业务层库中的DTO并在管理器中调用方法。 该经理将使用DTO并将其映射到一个或多个实体,并调用传递这些实体的存储库中的方法。 存储库返回实体,管理者使用这些实体构造DTO以发回。

有很多方法可以做到这一点,我敢肯定,唯一的方法就是唯一的方法。

您可以使用诸如Ninject之类的依赖项注入框架来实现进一步的分离和独立性。

以上仅仅是一个例子。 它可能对一组人有用,而另一组人则认为这是不可接受的。 它取决于许多因素,项目的规模是主要因素之一。

除了所有这些之外,总是从可管理的大小的体系结构开始,随着变更的需要,您将不断地进行重构,以适应单元测试中的模拟,Web应用程序中模型的数量变得难以管理或现在需要一个单独的团队来编写服务层,并且您不希望这样做干扰您的开发,现在服务层可能必须由其他UI层使用,而不仅仅是您的Web前端,等等。

几点:

  • 存储库中具有“业务逻辑”没有问题。 实际上,您的大多数“业务逻辑”都将存在。 您的存储库中包含查询,如果这些查询非常有趣,那么这些查询将与您的“业务逻辑”紧密相关。

  • 控制器中具有“业务逻辑”没有问题。 您的控制器正在控制您的UI,并且UI的工作方式是“业务逻辑”。

  • 根据定义,在分层体系结构中,每个层都知道其上一层的公共接口。 您的数据访问可以看到您域层的公共接口。 您的UI层可以看到服务层的公共界面。

  • 如果您的项目如此之小,以至于您有能力手动编码自己的数据访问层,而不是使用ORM或类似的代码,那么拥有完全脱钩的Starship Enterprise架构可能只会使您的生活最困难。 (因此,这意味着我认为您疯狂地编写了自己的数据访问层-至少尝试了像Dapper这样的轻量级框架)。

  • 根据您的需求进行选择。 问问自己“为什么X需要与Y解耦”。 答案可能是“所以我可以在对Y进行单元测试时模拟X”。 答案可能是“所以我可以在不需要知道Y的其他项目中使用X”。 如果找不到答案,请选择YAGNI。

暂无
暂无

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

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