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
Другие вопросы по тегам