Castle.Windsor Intercept Тип возврата операции WCF
Учитывая этот контракт на эксплуатацию:
<ServiceContract()>
Public Interface IService1
<OperationContract()>
Function GetData(ByVal composite As CompositeType) As CompositeType
End Interface
Я создаю клиент WCF, используя Castle.Windsor WCFClientFacility, например:
container.Register(Component.
For(Of IService1).
ImplementedBy(Of Service1)().
AsWcfClient(New DefaultClientModel() With {
.Endpoint = WcfEndpoint.
BoundTo(New BasicHttpBinding()).
At(String.Format("http://localhost:50310/{0}.svc", "Service1"))
}))
Это все работает нормально, но теперь я хочу иметь возможность прокси вернуть тип возврата операции GetData, CompositeType
, Просто регистрация CompositeType
в контейнере вот так:
container.Register(Component.For(Of CompositeType).Interceptors(GetType(MyInterceptor))
не сделал трюк... Возможно ли такое поведение? Целью этого было бы внедрение INPC на возвращаемый объект автоматически с использованием прокси / перехватчиков. Ключом будет возможность перехватить сериализатор, пока он активирует новый экземпляр CompositeType
?
1 ответ
Причина, по которой это не работает, заключается в том, что клиентский прокси-сервер Castle Windsor является просто оболочкой для клиентского прокси-сервера WCF, а клиентский прокси-сервер WCF создает объекты, возвращаемые методами обслуживания, которые они не отслеживают Castle Windsor. Однако вы можете перехватить методы клиентского прокси Castle Windsor, чтобы, когда он хочет вернуть CompositeType, вы получили вместо него возвращенный перехваченный прокси-объект.
Примечание. Чтобы это работало, CompositeType не должен быть NotInheritable, а любые методы, которые вы хотите перехватить, должны быть переопределенными.
container.Register(Component.
For(Of IService1).
ImplementedBy(Of Service1)().
AsWcfClient(New DefaultClientModel() With {
.Endpoint = WcfEndpoint.
BoundTo(New BasicHttpBinding()).
At(String.Format("http://localhost:50310/{0}.svc", "Service1"))
})
.Interceptors(Of ServiceInterceptor)
)
Также зарегистрируйте два перехватчика, один (ServiceInterceptor) для перехвата вызовов метода Service, и один (CompositeTypeInterceptor) для перехвата методов возвращаемого объекта:
container.Register(
Component.For(Of ServiceInterceptor)(),
Component.For(Of CompositeTypeInterceptor)()
)
Вот код ServiceInterceptor. Он перехватывает все методы и для любого, который возвращает CompositeType, вместо этого возвращает прокси для CompositeType, в котором все методы перехвачены CompositeTypeInterceptor:
Imports Castle.DynamicProxy
Imports System
Public Class ServiceInterceptor
Implements IInterceptor
Private _proxyGenerator As ProxyGenerator
Private _compositeTypeInterceptor As CompositeTypeInterceptor
Public Sub New(compositeTypeInterceptor As CompositeTypeInterceptor)
_proxyGenerator = New ProxyGenerator()
_compositeTypeInterceptor = compositeTypeInterceptor
End Sub
Public Sub Intercept(invocation As IInvocation) Implements IInterceptor.Intercept
invocation.Proceed()
If TypeOf invocation.ReturnValue Is CompositeType Then
invocation.ReturnValue = _proxyGenerator.CreateClassProxyWithTarget(Of CompositeType)(CType(invocation.ReturnValue, CompositeType), New IInterceptor() {_compositeTypeInterceptor})
End If
End Sub
End Class
А вот и код CompositeTypeInterceptor. Все, что он делает, это печатает отладочное сообщение, но вы можете изменить его, чтобы сделать то, что вы хотите.
Imports Castle.DynamicProxy
Imports System
Imports System.Diagnostics
Public Class CompositeTypeInterceptor
Implements IInterceptor
Public Sub Intercept(invocation As IInvocation) Implements IInterceptor.Intercept
Debug.Print("Intercepted " + invocation.Method.Name)
invocation.Proceed()
End Sub
End Class