1

Уровень обслуживания разделен на команду и сторону запроса, а на каждой стороне есть свои обработчики.Wcf с SimpleInjector бросает «Области WCF не могут быть вложенными»

Следующая конфигурация используется

// 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 делается с BackgroundWorker
  • Я использую Simple Injector версии 2.2.3
  • Global.asax, который строит контейнер
  • , размещенный в IIS
  • У каждого .svc установлена ​​разметка SimpleInjectorFactory
  • wsHttpBinding с сертификатом и обычая UserNamePasswordValidator
  • каждой конфигурации конечных точек имеет все необходимые значения, установленные для 2147483647.

ошибка происходит, когда я выполняю два запроса загрузки быстро последовательно, так что первый не завершен, а второй имеет место.

ответ

2

Это известная проблема с Simple Injector 2.2.3 для некоторых конфигураций WCF. Некоторые конфигурации WCF заставляют второй вызов IInstanceProvider.GetInstance. Методы SimpleInjectorInstanceProvider.GetInstance вызывают внутренний метод BeginScope, который ограничен одной областью.

Есть два решения:

Первое решение обновить до последней Simple Injector WCF Integration пакета. В выпуске 2.3.0 пакета интеграции WCF исправлена ​​эта проблема.

Второе решение состоит в том, чтобы не использовать операцию Per WCF вообще, но использовать масштаб продолжительности жизни (который похож на режим работы WCF). Это особенно хорошее решение в вашем случае, поскольку вы используете command handlers и query handlers. Другими словами, ваша служба WCF, вероятно, будет consist of just two WCF operations. Это упрощает перенос этих двух методов на всю жизнь, без необходимости беспокоиться, что код должен быть добавлен ко всем другим операциям в службе (так как ваша служба больше не будет работать).Ваша работа будет выглядеть следующим образом:

[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()); 
+0

Я даю второму решению, попробовать в течение следующих спринтов и ждать для обновления. Просто нужно изменить одну учетную запись и два метода в двух службах. – Khh

+1

второе решение было исправлено в пять минут и работает. замечательный, отличная поддержка! – Khh

Смежные вопросы