如何将 SimpleInjector for WCF 和 Web API 组合在一起



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

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

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

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

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

我目前实现了以下内容,以使用正确的作用域生活方式:

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);

最终是否可以使用相同的容器? (只要两个容器具有相同的注册,在两个容器上调用 Verify 也没有意义(

你基本上有 3 个选项:

  1. 使用两个容器实例
  2. 将一个容器实例与混合生活方式结合使用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作用域(时,简单注入器将使用WebApiRequestLifestyle。在没有此类范围的情况下,它将回退到使用WcfOperationLifestyle.

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

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

尽管可以在 Web API 应用程序中互换使用AsyncScopedLifestyleWebApiLifestyle,但这不适用于 WCF。这是因为 WCF 集成包使用的技术类似于ThreadScopedLifestyle,但使用自己的实现。

尽管您也可以在单线程应用程序上使用AsyncScopedLifestyle,但您必须替换当前启动 WCF 作用域的 WCF 的部分基础结构,以使其改为启动异步作用域。

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

相关内容

  • 没有找到相关文章

最新更新