Closed rogeralsing closed 6 years ago
Relates to #406
I tried to used something like that but ... Proto is not ready ... and it's not 4.5.2 compatible.
class OpenTracingDecorator<T> : DispatchProxy
{
private OpenTracingDecorator() { }
T _context;
public static T Create<T>(T context, SpanSetup sendSpanSetup, ITracer tracer)
{
var proxy = Create<T, OpenTracingDecorator<T>>();
var t = proxy as OpenTracingDecorator<T>;
t._context = context;
return proxy;
}
protected override object Invoke(MethodInfo targetMethod, object[] args)
{
if (targetMethod.Name == nameof(ISenderContext.RequestAsync))
throw new InvalidCastException("Just to know I passed here");
return targetMethod.Invoke(_context, args);
}
}
As our need is not that general, we could implement some "ContextBuilder" that will be able to add middleware/aspect for each methods :
props.WithContextDecorator(ctxBuilder => {
ctxBuilder.WithRequestAsync(async (next, target, message) => {
// do something before
var result = await next(target, message);
// do something after
};
});
I'm thinking if we just implement a base class for decorators, that manually forwards each call. no magic, just code.
Then the implementor of a decorator could just override the method they want to intercept
I've pushed this: https://github.com/AsynkronIT/protoactor-dotnet/blob/dev/src/Proto.Actor/ActorContextDecorator.cs
Inherit and override the request methods. that should at least technically work. Then we just need to make it all happen in the ActorContext so that the decorator is the one passed to the middlewares and the actor
I'm closing this one as it is done, we could open new issues if there are bugs or API design ideas
In an effort to intercept calls to methods of the different contexts. We need a decent way to decorate the context instances.
What I mean here is:
IContext.RequestAsync
→MyDecoratorContext.RequestAsync
→ActorContext.RequestAsync
And something similar for RootContext.
First of all, RootContext is currently just created with
new
, for this to work properly, we need some factory for root contexts.e.g. RootContext.Create() // returns an IRootContext with potential decorators wrapped
in the case of actors, it's easier. we can simply have a
WithContextDecorator
onProps
Then when the ActorContext invokes ReceiveAsync on the actor, we just pass the wrapper context.Thoughts ?