服务层分为命令端和查询端,每端都有自己的处理程序。
使用以下配置
// EF context
_container.RegisterPerWcfOperation<MyDbContext, MyDbContext>();
_container.RegisterManyForOpenGeneric(typeof(IHandler<>),
ApplicationAssemblies);
// many more regs but nothing special
SimpleInjectorServiceHostFactory.SetContainer(_container);
和所需的标记设置:
工厂= " SimpleInjector.Integration.Wcf.SimpleInjectorServiceHostFactory,SimpleInjector.Integration.Wcf "
抛出以下异常:
我认为错误发生在WCF作用域不能嵌套。
internal WcfOperationScope BeginScope()
WcfOperationScopeManager
实现的一些背景信息:
- WinForm应用程序
- QueryClient的执行是通过后台工作器完成的
- 我使用的是2.2.3版本的简单注入器
- 全球。构建容器 的asax
- 托管于IIS
- 每个.svc都有自己的标记集来使用
SimpleInjectorFactory
-
wsHttpBinding
带证书和海关UserNamePasswordValidator
- 每个端点配置都将所有需要的值设置为2147483647。
错误发生时,我执行两个加载请求快速连续,所以第一个没有完成,第二个发生。
这是简单注入器2.2.3中一些WCF配置的已知问题。一些WCF配置强制对IInstanceProvider.GetInstance
进行第二次调用。SimpleInjectorInstanceProvider.GetInstance
方法调用内部的BeginScope
方法,该方法仅限于一个作用域。
有两个解决方案:
第一个解决方案是升级到最新的Simple Injector WCF集成包。WCF集成包的2.3.0版本修复了这个问题。
第二个解决方案是根本不使用Per WCF操作,而是使用生命周期作用域(其工作方式类似于Per WCF操作方式)。对于您的情况,这是一个特别好的解决方案,因为您使用命令处理程序和查询处理程序。换句话说,您的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;
}
当然,所有使用每个WCF操作进行的注册都应该更改为生命周期范围:
_container.Register<MyDbContext, MyDbContext>(new LifetimeScopeLifestyle());