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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
| using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Messaging;
namespace De.Tutorials.Training
{
public class SimpleDynamicProxyExample
{
public static void Main(string[] args)
{
//Wir erzeugen unsere richtige Implementierung ...
ICalculator calcuatorImpl = new Calculator();
//Wir erzeugen unseren InvocationHandler der die Logik enthält die wir "um" unseren eigentlichen Methodenaufruf wrappen wollen
IInvocationHandler invocationHandler = new LoggingInvocationHandler();
invocationHandler.Target = calcuatorImpl;
// anstatt nur einen InvocationHandler zu definieren könnte man natürlich auch eine ganze Kette von InvocationHandlern (InvocationHandlerChain) registrieren, welche dann nacheinander abgearbeitet werden.
//Hier erzeugen wir unseren Proxy. Man kann hier den Proxy auf ICalculator casten, obwohl dieser das ICalculator interface
//nicht implementiert... das stimmt natürlich nicht ganz. Zur Laufzeit wird IL Code generiert, welcher das interface
//dynamisch zur laufzeit implementiert (daher der name DYNAMICProxy)
ICalculator calculatorProxy = (ICalculator)new GenericProxy(typeof(ICalculator),
calcuatorImpl,
invocationHandler).GetTransparentProxy();
Console.WriteLine(calculatorProxy.Add(1, 2));
}
}
public interface ICalculator
{
decimal Add(decimal x, decimal y);
decimal Sub(decimal x, decimal y);
}
public class Calculator : ICalculator
{
public decimal Add(decimal x, decimal y)
{
return x + y;
}
public decimal Sub(decimal x, decimal y)
{
return x - y;
}
}
public interface IInvocationHandler
{
object Target
{
get;
set;
}
object Invoke(object proxy, MethodBase methodBase, object[] arguments);
}
public class LoggingInvocationHandler : IInvocationHandler
{
public object Target
{
get { return target; }
set { target = value; }
} private object target;
public object Invoke(object proxy, MethodBase methodBase, object[] arguments)
{
Console.WriteLine("Before: " + methodBase.Name);
object result = methodBase.Invoke(target, arguments);
Console.WriteLine("After: " + methodBase.Name);
return result;
}
}
public class GenericProxy : RealProxy
{
public IInvocationHandler InvocationHandler
{
get { return invocationHandler; }
set { invocationHandler = value; }
} private IInvocationHandler invocationHandler;
public GenericProxy(Type type, object target, IInvocationHandler invocationHandler)
: base(type)
{
this.invocationHandler = invocationHandler;
}
public override IMessage Invoke(IMessage message)
{
IMethodCallMessage methodCallMessage = (IMethodCallMessage)message;
try
{
object result = invocationHandler.Invoke(this,
methodCallMessage.MethodBase,
methodCallMessage.InArgs);
return new ReturnMessage(result, null, 0, methodCallMessage.LogicalCallContext, methodCallMessage);
}
catch (TargetInvocationException targetInvocationException)
{
return new ReturnMessage(targetInvocationException, methodCallMessage);
}
}
}
} |