Skip to content

Instantly share code, notes, and snippets.

@wullemsb
Created February 20, 2024 19:00
public class DispatchProxyLoggingDecorator<T> : DispatchProxy
where T : class
{
public static T Decorate(T target, ILogger logger)
{
// DispatchProxy.Create creates proxy objects
var proxy = Create<T, DispatchProxyLoggingDecorator<T>>()
as DispatchProxyLoggingDecorator<T>;
// If the proxy wraps an underlying object, it must be supplied after creating the proxy.
proxy.Target = target;
proxy.Logger = logger;
return proxy as T;
}
public ILogger Logger { get; private set; }
public T Target { get; private set; }
protected override object Invoke(MethodInfo targetMethod, object[] args)
{
try
{
// Perform the logging that this proxy is meant to provide
Logger.LogInformation("Calling method {TypeName}.{MethodName} with arguments {Arguments}", targetMethod.DeclaringType.Name, targetMethod.Name, args);
var result = targetMethod.Invoke(Target, args);
// A little more logging
Logger.LogInformation("Method {TypeName}.{MethodName} returned {ReturnValue}", targetMethod.DeclaringType.Name, targetMethod.Name, result);
return result;
}
catch (TargetInvocationException exc)
{
// If the MethodInvoke.Invoke call fails, log a warning and then rethrow the exception
Logger.LogWarning(exc.InnerException, "Method {TypeName}.{MethodName} threw exception: {Exception}", targetMethod.DeclaringType.Name, targetMethod.Name, exc.InnerException);
throw exc.InnerException;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment