1

服务层分为命令和查询端,每一端都有自己的处理程序。

使用以下配置

// EF context
_container.RegisterPerWcfOperation<MyDbContext, MyDbContext>();
_container.RegisterManyForOpenGeneric(typeof(IHandler<>),
    ApplicationAssemblies);

// many more regs but nothing special

SimpleInjectorServiceHostFactory.SetContainer(_container);

以及所需的标记设置:

Factory="SimpleInjector.Integration.Wcf.SimpleInjectorServiceHostFactory, SimpleInjector.Integration.Wcf"

抛出以下异常:

WCF 范围不能嵌套。

我认为错误发生在

internal WcfOperationScope BeginScope()

WcfOperationScopeManager实施。

一些背景资料:

  • WinForm 应用程序
  • QueryClient 的执行是由后台工作人员完成的
  • 我正在使用 Simple Injector 2.2.3 版
  • 构建容器的 Global.asax
  • 托管在 IIS 中
  • 每个 .svc 都有要使用的标记集SimpleInjectorFactory
  • wsHttpBinding有证书和自定义UserNamePasswordValidator
  • 每个端点配置都将所有需要的值设置为 2147483647。

当我连续快速执行两个加载请求时会发生错误,因此第一个未完成而第二个发生。

4

1 回答 1

2

对于某些 WCF 配置,这是 Simple Injector 2.2.3 的一个已知问题。某些 WCF 配置会强制对IInstanceProvider.GetInstance. 这些SimpleInjectorInstanceProvider.GetInstance方法调用内部BeginScope方法,该方法仅限于一个范围。

有两种解决方案:

第一个解决方案是升级到最新的Simple Injector WCF 集成包。WCF 集成包的 2.3.0 版本修复了这个问题。

第二种解决方案是根本不使用 Per WCF Operation,而是使用生命周期范围(其工作方式类似于 Per WCF Operation 生活方式)。在您的情况下,这尤其是一个很好的解决方案,因为您使用command handlersquery handlers。换句话说,您的 WCF 服务可能只包含两个 WCF 操作。这使得将这两个方法包装在生命周期范围内变得非常容易,而无需担心必须将代码添加到服务中的所有其他操作中(因为您的服务将不再获得任何操作)。您的操作将如下所示:

[OperationContract]
public object Execute(dynamic command)
{
    Type commandHandlerType = typeof(ICommandHandler<>)
        .MakeGenericType(command.GetType());

    using (Bootstrapper.BeginLifetimeScope())
    {
        dynamic commandHandler = Bootstrapper.GetInstance(commandHandlerType);

        commandHandler.Handle(command);
    }

    return command;
}

当然,使用 Per WCF Operation 进行的所有注册都应更改为 Lifetime 范围:

_container.Register<MyDbContext, MyDbContext>(new LifetimeScopeLifestyle());
于 2013-06-19T13:41:50.957 回答