给定此操作契约:
<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