【问题标题】:How to use dependency injection and the repository pattern with ASP.NET web services?如何在 ASP.NET Web 服务中使用依赖注入和存储库模式?
【发布时间】:2009-09-20 00:07:30
【问题描述】:

对于常规的 ASP.NET MVC 页面,存储库被传递给控件的构造函数。然后测试可以实例化控制器在模拟存储库中传递。

如何使用 Web 服务做到这一点?我看到的问题是我们没有对应的 ControllerBuilder.SetControllerFactory。

让我的 IoC 框架 (Castle) 使用正确的存储库实现来实例化我的 Web 服务的最佳做法是什么?

我认为可能有一种方法可以扩展 HttpHandler 并改变 Web 服务的实际实例化方式。我相信这就是 MVC 框架的做法。

【问题讨论】:

  • 您使用哪种技术来实现您的网络服务? ASP.NET Web 服务还是 Windows Communication Foundation?
  • ASP.NET Web 服务。但是,在阅读 jrista 的回答后,我认为如果我真的想注入依赖项,那么研究 WCF 可能是值得的。我正在考虑只使用两个构造函数 - 一个将存储库作为参数(测试将调用这个)和一个默认的硬编码 :this(new IRepository) 并将由 ASP.NET 框架调用。

标签: asp.net web-services dependency-injection inversion-of-control


【解决方案1】:

这是个好问题。我也有同样的问题。我认为如果您使用 .asmx 文件创建 Web 服务,则不可能使用构造函数注入。如果您使用 WCF 来实现 Web 服务,那么我认为这是可能的。

在我的 .asmx Web 服务中,我让 DI 容器通过设置属性来设置依赖项。因为我的应用程序也是一个 web 表单 asp.net 应用程序,所以我必须这样做,因为我也不能在 web 表单上使用构造函数注入。但我使用的是 StructureMap,它有一个BuildUp 函数,可以设置已创建对象的属性。不像构造函数注入那么干净,但是一个很好的折衷方案。

但是 Web 服务与 Web 表单不同,因为我可以在 Application_PostMapRequestHandler 事件中将构建放在 Web 表单之外。但是我还没有发现在创建 Web 服务类之后触发的事件。因此,在我的 Web 服务的构造函数中,我有以下代码

ObjectFactory.BuildUp(this);

这是一种反模式。由 DI 容器初始化的类不应该知道 DI 容器本身。但是我还没有找到更好的解决方案。

【讨论】:

    【解决方案2】:

    我相信您正在寻找 Castle Windsor WCF 集成设施。它提供了一个 ServiceHost 实现,它利用 Windsor IOC 接管服务实现的构建过程。您可以像使用此工具的任何其他 IoC 应用程序一样注入依赖项,而且非常方便,它是 Castle 项目的一部分:

    http://www.castleproject.org/container/facilities/trunk/wcf/index.html

    如果 Castle Project 版本不能满足您的需求,我在找到 Castle 项目版本之前创建了自己的设施来为 Windsor 做同样的事情。他们通常都做同样的事情,但他们处理问题的方式也略有不同。

    【讨论】:

    • 我猜答案是“你不能在 ASP.NET Web 服务中使用构造函数注入”,所以要么使用 BuildUp(this) 要么使用 WCF 和城堡。
    • 实际上,您应该能够将 Castle Windsor 与 ASMX 风格的服务一起使用(如果您的意思是这样的话)。我以为您在询问 WCF,但我不明白为什么您也不能将 Windsor 集成到 ASMX 管道中。这可能不像使用 WCF 那样简单,但应该不是不可能的。
    • @jrista 因为在 asmx 文件中不允许使用 ServiceHost,您有任何关于如何为 asmx 服务实现 DI 的示例吗?
    【解决方案3】:

    定义一个基类并在其中使用属性注入。皮特已经说过了,但你会这样做:ObjectFactory.BuildUp(this);

    不同之处在于我会将它放在 Web 服务的基类中,因此对于特定的实现来说它是“自动的”。

    这样一来,我不会关心它,除非您明确需要在运行时切换 DI 容器(不太可能)。如果您仍然需要它,只需将调用移至将使用特定 DI 容器的单独类。

    【讨论】:

      【解决方案4】:

      是否有任何原因您不能使用所需的构造函数创建自定义类,然后在 asmx 中实例化该类的对象,然后将所有操作委托给该对象?

      我通常像这样创建这些类型的对象:

      var o = CustomClass.Create();
      
      public class CustomClass
      {
        public static CustomClass Create()
        {
          return IoC.Resolve<CustomClass>();
        }
      }
      
      public static class IoC
      {
        public T Resolve<T>()
        {
          return yourStaticReferenceToPreferredContainer.Resolve<T>();
        }
      }
      

      【讨论】:

        【解决方案5】:

        【讨论】:

          【解决方案6】:

          MS 实际上对此有一个解决方案:http://msdn.microsoft.com/en-us/library/ff664461(PandP.50).aspx

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-03-23
            • 1970-01-01
            • 1970-01-01
            • 2021-10-23
            • 1970-01-01
            相关资源
            最近更新 更多