Castle.Windsor拦截WCF操作返回类型

时间:2014-05-26 13:42:07

标签: wcf castle-windsor castle wcffacility

鉴于此操作合同:

<ServiceContract()>
Public Interface IService1

    <OperationContract()>
    Function GetData(ByVal composite As CompositeType) As CompositeType

End Interface

我使用Castle.Windsor WCFClientFacility创建一个WCF客户端,如下所示:

    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 个答案:

答案 0 :(得分:0)

这不起作用的原因是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