架构中的服务层 - DLL?

Service layer in Architecture - DLL?

我们正处于 .Net 中 medium/large 扩展应用程序的早期设计阶段,该系统具有三个不同的内部客户端(站点)(一个在单独的域中)连接,以及很多外部服务。

我们现在专注于连接的内部站点,我提出了一个经典的分层应用程序,具有接口层、服务层、业务逻辑层和数据访问层。

在图中,我们有一个连接到 MVC 应用程序的浏览器。控制器有一个服务项目的引用(每个 "Business Area" 可能有 类。例如,"PersonService")。 MVC 将直接引用此服务项目。在Service层,也会有一些WCF项目,将某些功能暴露给外部资源,其他内部站点和服务等

虽然 WCF 项目会连接到主服务 DLL 以从中获取共享功能。

然后服务项目直接引用包含所有业务逻辑的业务项目。然后它引用了数据访问项目,该项目具有 a/some Entity Framework 模型作为 SQL 服务器数据库的 ORM。

SharedLib 只是一个所有层都引用的项目,包含任何共享逻辑,但主要用于 DTO(数据传输对象)。 EF 模型在数据层中转换为 DTO,因为没有其他层引用 EF 模型。

但是 MVC 应用程序,通过应用程序内的直接引用连接到服务层,以及将 WCF 服务暴露给外部源和跨域内部站点。

我们遇到的问题是在服务层。我认为这应该是一个DLL,其他人说,如果没有WCF,那么表示应该直接连接到业务逻辑层。他们问,'Why add the extra layer and complexity of a service DLL here?'.

消除表示 'can' 直接连接到逻辑的服务层是否是一种好的做法?我看到了服务层的好处,它添加了业务和表示的明确隔离,并允许可扩展性。看起来确实像是通过 dll,但直接连接到 BL 似乎很奇怪。

是否有 pro/con 使用 DLL 可以证明 keeping/not 保留它的理由?

我在图片中看到了 MVVM 模式的提示,我会假设是这种情况,但它应该不会对答案产生真正的影响。

我不会有完美的答案,但不认为应该直接访问业务层。

我认为界面需要的任何功能都应该可以通过视图模型中的命令访问,这些命令使用可用的服务来执行它们的任务。

在我看来,业务层是业务规则,例如创建发票时的公式和预算映射。生成 P.O 的另一个示例。数.

另一方面,发票服务将负责应用您拥有的不同业务规则,以便生成、修改等(管理)您的发票。

当不需要把事情弄得太复杂时,我经常看到的是业务层将隐式包含在服务层中。

将服务层编译为 DLL 的最大优势在于它们可以由应用程序的不同部分(例如前端和后端)共享。例如,如果您使用 ASP.net 来构建前端,那么能够共享服务将是一个优势,但是如果您使用 angular.js 之类的东西,那么显然它们将无法使用使图书馆变得不那么受欢迎。

我还看到了 WebAPI 的提示,这是将客户端界面与基于服务器的后端分离的最新趋势。这种模式通常意味着客户端不了解您的业务逻辑或对您的后端知之甚少。发送 HTTP 请求以执行操作,API 根据操作(GET 与 POST)以确认或数据响应。

至于WCF部分我不是很熟悉,我个人用的是RabbitMQ

总而言之,我希望我的咆哮能给你一些思考,帮助你做出决定。

由于这是一个 C# .net 问题,我想我可以放心地假设您的解决方案将在 visual studio 中创建。就个人而言,如果有足够的目的将服务与业务逻辑分开,我会毫不犹豫地向我的解决方案添加一个额外的库项目,并添加对需要它的项目的引用。它根本不会增加太多开销,因为它的大部分是由 visual studio 管理的(如果在自动化构建时在命令行中,则为 msbuild)。

如前一段所述,我会在我的解决方案中创建库项目,因为管理它并不太复杂,而且它实际上有助于适当的名称空间管理,作为一个小奖励。

我认为你们不应该害怕拥有更多的 dll(同样取决于项目的规模)。如果你仔细想想,每次你在你的项目中添加一个 nuget 包,你实际上是在依赖另一个 dll。

我不打算解决服务交付层之上的任何问题;在服务层的设计中,您如何将服务结果交付给浏览器应该是中立的。我们目前使用完全客户端 UI 使用 AngularJS 并且它工作得非常好。

对我来说,拥有层的目的主要是允许抽象并允许用其他东西替换层,或者修改层的实现方式而不重写所有内容。所以在我的设计中,层层叠叠;所以服务层应该只使用存储库,存储库是唯一引用领域模型/核心业务逻辑的地方。

过去 4 年我一直在开发一个相当大的系统。我们开始使用 Windows Worfklow、WCF 和 MVC.Net。在第一次修订后(大约 6 个月),我们停止使用 Workflow 和 WCF - WCF 只增加了编码的复杂性和单调乏味。一旦我们弄清楚如何正确实施它,工作流仍然在我们重新包含的列表中。我们在每个 DLL 中使用我的 Emesary 消息传递系统,还使用 ​​EmesaryMSMQ 桥允许多台机器提供服务。 Emesary 允许您在项目中拥有一个基于接口的通知系统——而该桥允许您将某些通知(可靠地通过 MSMQ)桥接到其他进程。无论您使用什么方法,正确设计您的协议都非常重要。

我们有自己的私人 nuget 存储库 - 我希望我们能以这种方式开始,因为它真正专注于设计过程并确保可替换性。目前我们有一个由 IUnitOfWorkManager 提供的 IUnitOfWork 和一个提供基于 Reference Monitor 的对象级安全性的 IAuthorisationMediator。我花了一天左右的时间才习惯使用 NuGet,但这是一项很好的投资。

最后我建议不要使用 EF。尽管需要额外付费,但我建议使用 dataobjects.net(而且我不以任何方式加入,除非作为一个非常快乐的用户)。 最初我们选择 dataobjects.net 因为它是代码优先。我在 2012 年重新评估了 EF(代码优先)、NHibernate 和其他一些 ORM - 我们继续使用 dataobjects.net,因为它最容易编码并且具有最佳性能(对我们而言)。我不想在 ORM 的主题上过多地偏离主题,所以我最后会说我们最近在另一个项目中使用了 EF - 我们都希望我们没有使用它。


1 我们当时确实意识到 dataobjects.net 的创作者在一定程度上宣传了它,但我们的测试结果与他们的基本一致。