I was able to get this to work using DynamicProxy.ProxyGenerator
's CreateInterfaceProxyWithTargetInterface(..) .
I first created a dynamic proxy factory. This returns a proxy object, for which each method will be intercepted by the provided IInterceptor
:
public class MyDynamicallyDecoratedServiceClientFactory
{
readonly ProxyGenerator _proxyGenerator;
readonly IInterceptor _interceptor;
public MyServiceClientFactory(IInterceptor interceptor)
{
_interceptor = interceptor;
_proxyGenerator = new ProxyGenerator();
}
public IMyService Create()
{
IMyService proxy = _proxyGenerator.CreateInterfaceProxyWithTargetInterface<IMyService>(null, _interceptor);
return proxy;
}
}
I then implemented the interceptor. Upon each method call, this interceptor will be called, which will create a new IMyService
from the provided IMyServiceFactory
, and delegate the method call to that new instance.
public class MyServiceClientInterceptor : IInterceptor
{
readonly IMyServiceFactory _svcFactory;
public MyServiceClientInterceptor(IMyServiceFactory svcFactory)
{
_svcFactory = svcFactory;
}
public void Intercept(IInvocation invocation)
{
IMyService realService = _svcFactory.Create();
IChangeProxyTarget changeProxyTarget = invocation as IChangeProxyTarget;
changeProxyTarget.ChangeInvocationTarget(realService);
invocation.Proceed();
}
}
Finally, to make use of all this:
// Create a service factory (the to-be-decorated class)
IMyServiceFactory myRealServiceFactory = /* ... */;
// Create a factory that will create decorated services
MyServiceClientInterceptor interceptor =
new MyServiceClientInterceptor(myRealServiceFactory);
MyDynamicallyDecoratedServiceClientFactory svcFactory =
new MyDynamicallyDecoratedServiceClientFactory(interceptor);
// Create a service client
IMyService svc = svcFactory.Create();
// Use it!
svcProxy.A();