Как перехватчик Unity может определить, исходил ли вызов из WCF или из внутренней службы?
У меня есть служба WCF, подключенная перехватчиком Unity, и все вызовы уровня WCF перехватываются Unity для целей аудита. Тем не менее, похоже, что Unity перехватывает ВСЕ вызовы для разрешения интерфейса, независимо от того, исходил ли вызов из WCF или изнутри.
Рассмотрим следующий код:
[ServiceContract]
public interface IMyUtilityService
{
[OperationContract]
void DoUtilityStuff();
}
[ServiceContract]
public interface IMyService
{
[OperationContract]
void DoStuff();
}
class MyService : IMyService
{
public MyService(IMyUtilityService myUtilityService)
{
}
public void DoStuff()
{
}
}
Сервисные интерфейсы зарегистрированы в Unity с перехватом:
container.RegisterType<IMyUtilityService, MyUtilityService>(
new Interceptor<InterfaceInterceptor>(),
new InterceptionBehavior<PipelineInterceptor>());
container.RegisterType<IMyService, MyService>(
new Interceptor<InterfaceInterceptor>(),
new InterceptionBehavior<PipelineInterceptor>());
Когда к IMyService сделан вызов WCF, я получаю перехватчик, и это здорово, и я могу провести одитинг. Однако когда IMyService разрешен, перехватчик снова запускается, когда IMyUtilityService внедряется в конструктор IMyService.
Есть ли способ настроить Unity для предотвращения этого? Или внутри перехватчика есть способ определить, что перехват был вызван WCF? Или мне нужно создать другой интерфейсный слой для разделения внешних вызовов и внутренних вызовов?
2 ответа
Мне удалось решить вопрос с креативной регистрацией сервисов в Unity. Ранее служба была зарегистрирована в Unity как внутренняя служба или как служба WCF с перехватом. Если служба WCF затем используется внутренне, возникают проблемы с перехватчиком.
Примечание: проблема с перехватчиком могла быть из-за того, что мы использовали отложенное разрешение зависимостей.
Проблема может быть решена путем регистрации всех служб в Unity для внутреннего разрешения, а затем регистрации служб WCF с явными именами. Когда конечная точка WCF активирована, экземпляр может быть разрешен с использованием явного имени.
Например, регистрация службы:
container.RegisterType(interfaceType, implementationType);
if (isWCF)
container.RegisterType(
interfaceType,
implementationType,
"WCF", // name for resolving WCF services
new Interceptor<InterfaceInterceptor>(),
new InterceptionBehaviour<PipelineInterceptor>());
И затем создание экземпляра в провайдере экземпляра:
public object GetInstance(InstanceContext instanceContext, Message message)
{
return _container.Resolve(_interfaceType, "WCF");
}
Решение является предпочтительным, так как перехватчик теперь только зарегистрирован и активирован против вызова служб WCF.
Самый простой способ - проверить, есть ли у вас OperationContext.
if (OperationContext.Current != null)
{
// Called through WCF.
}
else
{
// Not WCF.
}
И в перехватчике.
public class PipelineInterceptor : IInterceptionBehavior
{
public bool WillExecute
{
get { return OperationContext.Current != null; }
}
// Other ...
}