城堡.温莎拦截WCF操作返回类型



给定此操作契约:

<ServiceContract()>
Public Interface IService1
    <OperationContract()>
    Function GetData(ByVal composite As CompositeType) As CompositeType
End Interface

我使用城堡创建了一个WCF客户端。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的新实例时拦截它的可能性

这不起作用的原因是Castle Windsor客户端代理只是WCF客户端代理的包装器,并且由于WCF客户端代理创建了由服务方法返回的对象,因此Castle Windsor不会跟踪这些对象。但是,您可以拦截Castle Windsor客户端代理的方法,以便当它想要返回CompositeType时,您可以让它返回被拦截的代理对象。

注意:要使其工作,CompositeType必须不是NotInheritable,并且您想要拦截的任何方法必须是Overridable。

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的代理,而不是由CompositeType拦截的所有方法:

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

最新更新