2

私は時折、コレクション クラス アダプタを作成する必要がありました。つまりIList<T>、メソッドのプロキシを実装するクラス用のアダプタを作成し、いくつかの追加機能を追加しました。インターフェイスには多数のIListメソッド/プロパティがありますが、ストレート スルー プロキシ メソッドを動的に実装できるかどうか疑問に思っていました。を調べましたDynamicObjectが、DTO クラスをプロキシする単純な例、つまりプロパティだけを持つクラスをプロキシする例しか見つかりませんでした。

プロキシはIList<T>可能ですか?

例えば

public class ListProxy : IList<T>
{
  private IList<T> _adaptee;

  public ListProxy(IList<T> adaptee)
  {
    _adaptee = adaptee
  }

  // dynamically implement straight-through IList methods / properties
}
4

1 に答える 1

2

このようなもの?

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;

class Program
{
    static void Main(string[] args)
    {
        IList<string> listProxy = MyProxyGenerator.Create<IList<string>>(new ListProxy<string>(new List<string>() { "aa","bb" }));
        bool b1 = listProxy.Contains("aa");
        bool b2 = listProxy.Contains("cc");
        int count = listProxy.Count;
        string s = listProxy[1];
    }

    public class ListProxy<T>
    {
        private IList<T> _adaptee;

        //Only method needed by proxy generator
        object Adaptee
        {
            get { return _adaptee; }
        }

        public ListProxy(IList<T> adaptee)
        {
            _adaptee = adaptee;
        }
    }

    class MyProxyGenerator : RealProxy
    {
        Type _Type;
        object _Instance;

        public static T Create<T>(object instance)
        {
            return (T)new MyProxyGenerator(typeof(T),instance).GetTransparentProxy();
        }

        MyProxyGenerator(Type type,object instance) : base(type)
        {
            _Type = type;
            _Instance = instance.GetType().InvokeMember("get_Adaptee", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, instance, null);
        }

        public override IMessage Invoke(IMessage msg)
        {
            IMethodCallMessage methodMessage = new MethodCallMessageWrapper((IMethodCallMessage)msg);
            string method = (string)msg.Properties["__MethodName"];
            object[] args = (object[])msg.Properties["__Args"];

            object retObj = _Instance.GetType().InvokeMember(method, BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod,null,_Instance,args);
            return new ReturnMessage(retObj,methodMessage.Args,methodMessage.ArgCount,methodMessage.LogicalCallContext,methodMessage);
        }
    }


}
于 2011-10-05T08:40:27.127 に答える