Created
March 18, 2009 13:43
-
-
Save mayuki/81125 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Runtime.InteropServices; | |
using System.Runtime.Remoting; | |
using System.Reflection; | |
using System.Security.Policy; | |
using System.Xml.Serialization; | |
using System.Runtime.Remoting.Proxies; | |
using System.Runtime.Remoting.Messaging; | |
namespace ConsoleApplication1 | |
{ | |
public class A : MarshalByRefObject | |
{ | |
public event EventHandler HandleEvent; | |
public void FireEvent() | |
{ | |
if (HandleEvent != null) | |
HandleEvent(this, EventArgs.Empty); | |
} | |
public void Handler(Object sender, EventArgs e) | |
{ | |
Console.WriteLine("inside A"); | |
} | |
} | |
public class EventMangedProxy<T> : RealProxy where T : MarshalByRefObject | |
{ | |
private static readonly Dictionary<MethodInfo, EventInfo> EventsByAddMethods = new Dictionary<MethodInfo, EventInfo>(); | |
private static readonly Dictionary<MethodInfo, EventInfo> EventsByRemoveMethods = new Dictionary<MethodInfo, EventInfo>(); | |
private T _targetObject; | |
private Dictionary<EventInfo, List<Delegate>> _eventHandlers = new Dictionary<EventInfo, List<Delegate>>(); | |
static EventMangedProxy() | |
{ | |
foreach (var ev in typeof(T).GetEvents()) | |
{ | |
EventsByAddMethods.Add(ev.GetAddMethod(), ev); | |
EventsByRemoveMethods.Add(ev.GetRemoveMethod(), ev); | |
} | |
} | |
public EventMangedProxy(T aObj) | |
: base(typeof(T)) | |
{ | |
_targetObject = aObj; | |
} | |
public void RemoveAllEvents() | |
{ | |
foreach (var evHandlers in _eventHandlers) | |
{ | |
EventInfo evInfo = evHandlers.Key; | |
foreach (var evHandler in evHandlers.Value) | |
evInfo.RemoveEventHandler(_targetObject, evHandler); | |
} | |
} | |
public override IMessage Invoke(IMessage msg) | |
{ | |
IMethodMessage methodMessage = msg as IMethodMessage; | |
MethodInfo methodInfo = (MethodInfo)methodMessage.MethodBase; | |
if (EventsByAddMethods.ContainsKey(methodInfo)) | |
{ | |
EventInfo eventInfo = EventsByAddMethods[methodInfo]; | |
if (!_eventHandlers.ContainsKey(eventInfo)) | |
_eventHandlers[eventInfo] = new List<Delegate>(); | |
_eventHandlers[eventInfo].Add((Delegate)methodMessage.Args[0]); | |
} | |
else if (EventsByRemoveMethods.ContainsKey(methodInfo)) | |
{ | |
EventInfo eventInfo = EventsByRemoveMethods[methodInfo]; | |
if (_eventHandlers.ContainsKey(eventInfo)) | |
_eventHandlers[eventInfo].Remove((Delegate)methodMessage.Args[0]); | |
} | |
return RemotingServices.ExecuteMessage(_targetObject, (IMethodCallMessage)msg); | |
} | |
} | |
public class Program : MarshalByRefObject | |
{ | |
static void Main(string[] args) | |
{ | |
A aObjOrig = new A(); | |
EventMangedProxy<A> evProxy = new EventMangedProxy<A>(aObjOrig); | |
A aObj = (A)evProxy.GetTransparentProxy(); | |
// 直接削除されないイベントを追加 | |
aObjOrig.HandleEvent += aObjOrig.Handler; | |
aObjOrig.HandleEvent += (sender, e) => { Console.WriteLine("Maumau"); }; | |
// プロクシ経由で削除されるイベントを追加 | |
aObj.HandleEvent += aObj.Handler; | |
aObj.HandleEvent += (sender, e) => { Console.WriteLine("Hauhau"); }; | |
// イベントを実行 (4つ結果が出るはず[inside A, Maumau, inside A, Hauhau]) | |
aObj.FireEvent(); | |
// プロクシ経由で追加したイベントを削除 | |
evProxy.RemoveAllEvents(); | |
// イベントを追加 | |
aObj.HandleEvent += (sender, e) => { Console.WriteLine("Gaogao"); }; | |
// イベントを実行 (3つになるはず[inside A, Maumau, Gaogao]) | |
aObj.FireEvent(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment