【问题标题】:Should the services in my service layer live in separate projects/DLLs/assemblies?我的服务层中的服务是否应该存在于单独的项目/DLL/程序集中?
【发布时间】:2012-05-12 04:32:36
【问题描述】:

我目前正在开发一个 ASP.NET MVC 3 应用程序。我正在实现一个服务层,它包含业务逻辑,并由控制器使用。服务本身利用存储库进行数据访问,而存储库使用实体框架与数据库通信。

所以从上到下是:控制器 > 服务层 > 存储库(每个服务层都依赖于一个可注入的存储库)> 实体框架 > 单个数据库。

我发现自己正在制作诸如 UserService、EventService、PaymentService 等项目。

在服务层,我会有这样的功能:

  • ChargePaymentCard(int cardId, decimal amount)(部分 支付服务)
  • ActivateEvent(int eventId)(EventService 的一部分)
  • SendValidationEmail(int userId)(用户服务的一部分)

另外,作为我使用它的第二个地方的示例,我有另一个简单的控制台应用程序,它作为计划任务运行,它利用了这些服务中的一个。还有一个即将推出的第二个 Web 应用程序需要使用多个这些服务。

此外,我想让我们对拆分事物(例如我们的单个数据库)保持开放态度,并在未来转向面向服务的架构,并将其中的一些拆分为 Web 服务(甚至可以想象有朝一日被非.NET 应用程序使用)。我一直在睁大眼睛寻找可能使向 SOA 的飞跃在未来变得不那么痛苦的步骤。

我已经开始为每个服务创建一个单独的程序集 (DLL),但我想知道我是否走错了路。我正在尝试保持灵活性并保持松散耦合,但是这条路径对我有任何帮助(朝向 SOA 或一般而言),还是只是增加了复杂性?我应该改为创建一个包含整个服务层的程序集/dll,并在需要使用任何服务的地方使用该单个程序集吗?

我不确定我开始的路径的含义,因此我们将不胜感激!

【问题讨论】:

  • 哇,这是一个大问题:) - 需要几个项目:应用程序有多大?您希望看到多少负载?这是什么类型的应用程序?由于很多答案将取决于整个项目的一般信息......

标签: asp.net asp.net-mvc-3 soa service-layer


【解决方案1】:

最好将服务与消费者分开。在我们的项目中,我们有两个层次的分离。我们曾经将所有服务接口分组到一个 Visual Studio 项目中。所有服务实现都被分组到另一个项目中。 服务的使用者需要引用两个 dll,但它使解决方案更具可维护性和可扩展性。我们可以有多种服务实现。 例如服务接口可以在接口项目中为 WebSearch 定义一个契约。并且可以通过不同的搜索服务提供商(如 Google 搜索、Bing 搜索、Yahoo 搜索等)实现 WebSearch 的多种实现。

【讨论】:

    【解决方案2】:

    每个服务都有一个 DLL 听起来是个坏主意。根据 Microsoft 的说法,由于性能问题(来自 herethis post),您希望将一个大型程序集放在多个较小的程序集之上。

    我会将您的基础或核心服务拆分为一个单独的项目,并将大部分(如果不是全部)服务保留在其中。根据您的需要,您可能拥有仅在 Web 项目或控制台应用程序上下文中有意义的服务,而在其他任何地方都没有。这些服务不应成为“核心”服务层的一部分,而应驻留在相应的项目中。

    【讨论】:

    • 谢谢,这是一个很好的答案。希望我能标记两个答案!
    • 对于表演,您可以随时选择稍后将您的 dll 合并为一个。但是,将每项服务放在单独的项目中是一个坏主意的说法并没有实质内容。真的不是。这是一个好主意,它提高了可维护性和可重用性,并限制了循环引用的风险。
    【解决方案3】:

    IMO - 答案是取决于您的应用程序的很多因素。

    假设您正在构建一个重要的应用程序(即不是学习 SOA 的大学/爱好项目):

    • 用户服务/事件服务/支付服务 -- 创建自己的 DLL 并将其公开为 WCF 服务,如果有多个应用程序使用此服务,并且将 DLL 共享给不同的应用程序风险太大
      -- 这些服务之间不应相互依赖,应专注于各自的领域
      -- 注意:这些服务可能共享一些常见的服务,如日志记录、身份验证、数据访问等。

    • 创建组合服务 -- 此服务将组合所有其他服务的调用
      -- 例如:如果您已下订单并且业务流程为已下订单 > 确认用户存在(用户服务)> 引发 OrderPlaced 事件(事件服务)> 确认付款(付款服务)
      -- 所有这样的服务调用组合都可以在这一层处理
      -- 同样,根据环境,您可以选择将此服务公开为自己的 DLL 和/或将其公开为 WCF
      -- 注意:这是唯一一个共享对其他服务的引用的服务,并且是单点组合

    现在 - 使用此布局 - 如果您想单独与该服务交互,您将可以选择直接调用服务,如果您需要不同服务的业务工作流程,则需要调用组合服务完成交易。

    作为起点,我建议您阅读任何有关 SOA 架构的书籍 - 这将有助于理清很多概念。

    我试图尽可能简短以使这个答案有意义,有很多方法可以做同样的事情,这只是可能的方法之一。

    HTH。

    【讨论】:

    • 感谢您的回答。因此,此时我将组合回单个 DLL。这是一个重要的业务应用程序,但我们目前的流量非常低(启动)。我在想,我们可能希望拥有,比如说,UserService 和 PaymentService 网络化,并存在于不同的盒子上。听起来将它们保存在单个 DLL 中并没有太多偏离这种潜力,我会在我决定进一步向 SOA 推进时将它们分开?
    • 是的,您可以将它们拆分为不同的时间点,但请记住不要将它们耦合在一起,以便轻松完成拆分。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-23
    • 2012-07-01
    • 1970-01-01
    • 2017-07-18
    • 2014-11-11
    • 2016-05-12
    • 1970-01-01
    相关资源
    最近更新 更多