【问题标题】:How to combine SimpleInjector for WCF and Web API如何结合 SimpleInjector for WCF 和 Web API
【发布时间】:2017-07-21 23:47:31
【问题描述】:

我有一个同时托管 WCF 和 Web API V2 ApiControllers 的 Web 项目。

两者都应该从使用 SimpleInjector 中受益。

这 2 种技术有 2 个不同的 nuget 包:

  • SimpleInjector.integration.WebApi
  • SimpleInjector.Ingegration.Wcf

在给定的情况下,两者的注册应该相同,解决此问题的最佳方法是什么? 我是否应该创建 2 个不同的容器,因为范围仅在请求打开时才有效?

我目前实现了以下,以使用正确的 ScopedLifestyles:

    public static void ConfigureForWCF(Container container)
    {
        container.Options.DefaultScopedLifestyle = new WcfOperationLifestyle();

        RegisterImplementations(container);
    }

    public static void ConfigureForWebAPI(Container container)
    {
        container.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle();

        RegisterImplementations(container);
    }

    public static void RegisterImplementations(Container container)
    {
        // registrations for both WCF and Web API in here
        container.Register<IMyInterface, MyClass>();

我知道这样称呼他们:

        // container for WCF
        var containerWCF = new Container();

        SimpleInjectorConfiguration.ConfigureForWCF(containerWCF);

        containerWCF.Verify();

        // use the container for WCF
        SimpleInjectorServiceHostFactory.SetContainer(containerWCF);



        // container for Web API
        var containerWebAPI = new Container();

        SimpleInjectorConfiguration.ConfigureForWebAPI(containerWebAPI);

        // this doesn't currently make sense for me as the controllers inheriting from ApiController get registered as Transient 
        //containerWebAPI.RegisterWebApiControllers(GlobalConfiguration.Configuration);
        // instead I will register the Controllers manually

        containerWebAPI.Verify();

        // use the container for Web API
        GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(containerWebAPI);

最终有可能使用同一个容器吗? (只要它们具有相同的注册,在两个容器上调用验证也没有意义)

【问题讨论】:

    标签: c# wcf asp.net-web-api asp.net-web-api2 simple-injector


    【解决方案1】:

    你基本上有 3 个选项:

    1. 使用两个容器实例
    2. 使用一个带有hybrid lifestyle 的容器实例,它混合了WebApiRequestLifestyleWcfOperationLifestyle
    3. 使用一个容器并为 WCF 和 Web API 使用相同的生活方式。这通常是AsyncScopedLifestyle

    是否可以拥有两个容器取决于几个值,例如应该在整个 AppDomain 中恰好存在一次的服务数量。当您有 2 个容器实例时,每个都有自己的单例实例,因此您应该为每个容器提供一个现有实例。这可能很麻烦,但在大多数情况下,容器获取自己的单例实例应该不是问题。

    另一方面,拥有 2 个容器意味着您必须使用一些共享逻辑来填充两个容器实例共享的注册。这会使事情复杂化。

    另一方面,拥有两个容器确实允许两个服务以隔离的方式运行,这可能是有益的。

    如果您选择拥有一个容器实例,那么使用混合生活方式将是最明显的解决方案,尤其是因为 WCF 使用的范围技术(基于 ThreadScopedLifestyle)与 Web API 范围技术(后者基于AsyncScopedLifestyle)。因此,最简单的解决方案是将它们注册为混合,如下所示:

    container.Options.DefaultScopedLifestyle = Lifestyle.CreateHybrid(
        defaultLifestyle: new WebApiRequestLifestyle(),
        fallbackLifestyle: new WcfOperationLifestyle());
    

    使用此配置,当存在活动的 Web API 范围(即 AsyncScopedLifestyle 范围)时,Simple Injector 将使用 WebApiRequestLifestyle。如果没有这样的范围,它将回退到使用WcfOperationLifestyle

    如果您希望拥有一个容器,这将是最简单的解决方案。

    最后一个选项是为 WCF 和 Web API 应用程序使用一种特定范围的生活方式。由于 Web API 本质上是异步的,因此唯一明显可以使用的生活方式是 AsyncScopedLifestyle。借助 ASP.NET Core,我们实际上正在摆脱特定于自定义框架的生活方式,而主要使用 AsyncScopedLifestyle

    虽然您可以在 Web API 应用程序中交替使用 AsyncScopedLifestyleWebApiLifestyle,但这不适用于 WCF。这是因为 WCF 集成包使用了类似于 ThreadScopedLifestyle 的技术,但使用了自己的实现。

    虽然您也可以在单线程应用程序上使用 AsyncScopedLifestyle,但您必须替换当前启动 WCF 范围的 WCF 基础结构的一部分,以使其启动异步范围。

    由于这需要做更多的工作,我会选择使用 2 个容器,或者使用混合生活方式。

    【讨论】:

    • 很棒的答案。谢谢!现在我只需要弄清楚,为什么我的 ApiControllers 会通过 RegisterWebApiControllers 注册到 Transient 范围内。由于 ApiController 实现了 IDisposable,这似乎没有意义。
    • 控制器注册为瞬态,因为这是最方便的。它们由 Web API 处理。
    • 嗯,那么 container.Verify() 现在怎么能解决这个问题呢?它将返回...控制器注册为瞬态,但实现 IDisposable。抱歉,题外话
    • 如果调用 RegisterWebApiControllers 则不应发生。该方法会抑制该特定警告。你在做一些奇怪的事情:)
    • :) 感谢您提供的信息。我在 global.asax 的 Application_Start 中运行所有配置,首先是 AutoMapper,而不是上面的一堆 SimpleInjector 命令,最后我为 WebAPI 注册路由。当我有时间时会检查它..再次感谢您提供了很好的见解。特别感谢您在 SI 中所做的工作!
    猜你喜欢
    • 1970-01-01
    • 2011-10-09
    • 2014-05-13
    • 2017-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-24
    • 1970-01-01
    相关资源
    最近更新 更多