-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMethodProxy.cs
62 lines (49 loc) · 2.05 KB
/
MethodProxy.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
using System;
using System.Diagnostics;
using System.Reflection;
namespace Decorating
{
//https://stackoverflow.com/questions/38467753/realproxy-in-dotnet-core
public class MethodProxy<T> : DispatchProxy where T : class
{
private T _decorated;
private Stopwatch _stopwatch;
protected override object Invoke(MethodInfo targetMethod, object[] args)
{
try
{
Before(targetMethod, args);
var result = targetMethod.Invoke(_decorated, args);
After(targetMethod, args, result);
return result;
}
catch (Exception ex)
{
LogException(ex.InnerException ?? ex, targetMethod);
}
return null;
}
public static T Create(T decorated)
{
object proxy = Create<T, MethodProxy<T>>();
((MethodProxy<T>)proxy).SetParameters(decorated);
return (T)proxy;
}
private void SetParameters(T decorated) =>
_decorated = decorated ?? throw new ArgumentNullException(nameof(decorated));
private void LogException(Exception exception, MethodInfo methodInfo = null) =>
Console.WriteLine($"Class {_decorated.GetType().FullName}, Method {methodInfo.Name} threw exception:\n{exception}\n");
private void Before(MethodInfo methodInfo, object[] args)
{
_stopwatch = new Stopwatch();
_stopwatch.Start();
Console.WriteLine($"Class {_decorated.GetType().FullName}, Method {methodInfo.Name} is executing with args: {string.Join(", ", args)}\n");
}
private void After(MethodInfo methodInfo, object[] args, object result)
{
_stopwatch.Stop();
var ellapsed = _stopwatch.Elapsed.TotalMilliseconds;
Console.WriteLine($"Class {_decorated.GetType().FullName}, Method {methodInfo.Name} executed in {ellapsed}ms, Output: {result}\n");
}
}
}