2005年05月13日

RealProxy を使った簡単なサンプル

   このエントリーをはてなブックマークに追加 Clip to Evernote
RealProxy を使った最も簡単だと思われるサンプルをいくつかの Web ページを参考にしながら書いて見ました。
簡単なだけあって、まったく実用的ではありません。
using System;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Messaging;
using System.Reflection;

namespace IMethodMessageSample {
class Class1 {
[STAThread]
static void Main(string[] args) {
MyProxyClass mpc = new MyProxyClass(typeof(SampleClass));
SampleClass o = mpc.GetTransparentProxy() as SampleClass;
o.Print("あいうえお");
int n = o.Add(10,20);
Console.WriteLine(n.ToString());
Console.ReadLine();

}
}

public class SampleClass : MarshalByRefObject {
public void Print(string s) {
Console.WriteLine(s);
}
public int Add(int a, int b) {
return a + b;
}
}

public class MyProxyClass : RealProxy {
private Object myObjectInstance = null;
private Type myType = null;

public MyProxyClass(Type argType) : base(argType) {
myType = argType;
myObjectInstance = Activator.CreateInstance(argType);
}

public override IMessage Invoke(IMessage message) {
IMethodMessage myMethodMessage = (IMethodMessage)message;

Object returnValue = myType.InvokeMember( myMethodMessage.MethodName,
BindingFlags.InvokeMethod, null, myObjectInstance,
myMethodMessage.Args );
ReturnMessage myReturnMessage = new ReturnMessage( returnValue, null, 0,
((IMethodCallMessage)message).LogicalCallContext,
(IMethodCallMessage)message );
return myReturnMessage;
}
}
}
代理クラスを作るには、RealProxyからクラスを派生させます。用意するのはコンストラクタとInvoke メソッド。
コンストラクタでは、Activator.CreateInstance で、利用するクラスのインスタンスを生成します。
Invoke の中では、引数の情報を頼りに、リフレクションの機能を使って、実際のメソッドを呼び出し、ReturnMessage に戻り値の情報をセットし、戻ります。
new ReturnMessage の4つめの引数は、この場合は、nullでも良いような気がします。このあたりが、.NET Framework のドキュメントを読んでも良くわかりませんでした。
代理クラスを使う側は、代理クラスに実際のクラス情報を引数で渡し、代理クラスのインスタンスを生成します。
その後、GetTransparentProxy で、透過プロキシーを取り出し、それを実際のクラスにキャストします。
それ以降は、透過プロキシーを使って、あたかも実際のクラス(ここでは、SampleClass)を扱っているかのごとく、メソッド等を呼び出せます。
なお、SampleClass は、MarshalByRefObject の子孫クラスでないとダメみたいです。

まだまだ、RealProxy のさわりの部分ですが、結構難しいですね。やさしい解説ってどこかにないかな?


この記事へのコメント
透過プロキシの学習をしていて、非常に参考になりました!
ありがとうございます。
Posted by CrimsonPork at 2009年03月18日 19:01
CrimsonPorkさん
余計なコードをそぎ落としたので、何の役に立つのかわからないコードになってしまいましたが、お役に立てて何よりです。
Posted by gushwell at 2009年03月18日 20:05
 

この記事へのトラックバックURL

http://trackback.blogsys.jp/livedoor/gushwell/21880825