++C++; // 未確認飛行 C

Google
Web ufcpp.net

[サンプル] 透過プロキシ

目次

キーワード

概要

(書きかけ)

実行時型情報」 のサンプルがちょっと不足してるなぁと思って作ったもの。

.NET Framework では、RealProxy というクラスを使って、 インターフェースのメソッド呼び出しを横取りして独自の処理に置き換えることができます。

RealProxy

例えば、マルチキャストデリゲートのようなことをインターフェースのメソッド呼び出しに対して行うようなプロキシ。

RealProxy クラスを継承して、Invoke メソッドをオーバーライドするだけ。

public class MulticastProxy<Interface> : RealProxy
{
    public MulticastProxy(params Interface[] interfaces)
        : base(typeof(Interface))
    {
        this.interfaces = new List<Interface>(interfaces);
    }

    public override IMessage Invoke(IMessage msg)
    {
        IMethodMessage mm = msg as IMethodMessage;

        MethodInfo method = typeof(Interface).GetMethod(
            mm.MethodName, (Type[])mm.MethodSignature);
        object[] args = mm.Args;

        foreach (var i in this.interfaces)
        {
            method.Invoke(i, args);
        }

        return new ReturnMessage(
            null, null, 0, mm.LogicalCallContext, (IMethodCallMessage)msg);
    }

    private List<Interface> interfaces;
}

使う側では、GetTransparentProxy を呼んでプロキシ生成。

interface IAnimal
{
    void Bark();
}

class Cat : IAnimal
{
    public void Bark() { Console.Write("にゃー\n"); }
}

class Dog : IAnimal
{
    public void Bark() { Console.Write("わん\n"); }
}

class Mouse : IAnimal
{
    public void Bark() { Console.Write("ちゅー\n"); }
}

class Program
{
    static void Main(string[] args)
    {
        // 猫、犬、鼠を1匹ずつ登録。
        var proxy = new MulticastProxy<IAnimal>(
            new Cat(),
            new Dog(),
            new Mouse()
            );

        IAnimal animals = (IAnimal)proxy.GetTransparentProxy();

        animals.Bark(); // ちゃんと3匹とも鳴く。
    }
}

リフレクション使いまくるとパフォーマンスがでないので、 パフォーマンスが必要なら動的にアセンブリ言語はいたり、かなり変態的なことする必要があったりしますが。

Transtation into English

[お問い合わせ](q)