实现.net下的动态代理(续)-多对象Mixin

实现.net下的动态代理 一文使用动态代理实现了 Ducking Typing,解决了文中的第一个问题,下面,向第二个问题进军——mixin。

一、应用场景

(1) 假定有一个接口TInterface,一个类B,类C。类B与类C分别实现了部分TInterface:

 1    public interface TInterface
 2    {
 3        String A get; }
 4        String B(int a, int b);
 5    }

 6
 7    public class ClassB
 8    {
 9        public String A
10        {
11            get
12            {
13                return String.Empty;
14            }

15            set
16            { }
17        }

18    }

19
20    public class ClassC
21    {
22        public String B(int a, int b)
23        {
24            return (a + b).ToString();
25        }

26    }

 

假设b和c分别是B和C的一个实例,通过 TypeTemplate.Create<TInterface>(b,c) 方法将b和c包装一下,即可生成一个TInterface实例:

1            ClassB b = new ClassB();
2            ClassC c = new ClassC();
3            TInterface i2 = TypeTemplate.Create<TInterface>(b, c);
4

 

(2) 通过Mixin,我们还可以在运行时动态替换接口的指定方法或属性:

 1    public interface Human
 2    {
 3        String Heart();
 4        String Lung();
 5        String Name();
 6    }

 7
 8    public class ZhouBapi : Human
 9    {
10        public String Heart() return "好心"; }
11        public String Lung() return "好肺"; }
12        public String Name() return "周扒皮"; }
13    }

14
15    public class Huaidan
16    {
17        public String Heart() return "狼心"; }
18        public String Lung() return "狗肺"; }
19    }

20
21    class Program
22    {
23        static void Show(Human body)
24        {
25            Console.WriteLine(String.Format("我叫{0},我是{1}{2}", body.Name(), body.Heart(), body.Lung()));
26        }

27
28        static void ShowHuaidan(Human body)
29        {
30            Console.WriteLine(String.Format("{0},我看你是{1}{2}", body.Name(), body.Heart(), body.Lung()));
31        }

32
33        static void Main(string[] args)
34        {
35            Human zhou = new ZhouBapi();
36            Console.Write("周扒皮: ");
37            Show(zhou);
38            zhou = TypeTemplate.Create<Human>(new Huaidan(), zhou);
39            Console.Write("人民群众:");
40            ShowHuaidan(zhou);
41            Console.Read();
42        }

43    }

 

输出为:

周扒皮: 我叫周扒皮,我是好心好肺
人民群众:周扒皮,我看你是狼心狗肺

 

二、实现

以下是详细实现代码:

 

Code

 

测试代码:

 1        [TestMethod]
 2        public void TestCreate()
 3        {
 4            ClassA a = new ClassA();
 5            TInterface i1 = TypeTemplate.Create<TInterface, ClassA>(a);
 6            Assert.AreNotEqual(null, i1);
 7            Assert.AreEqual("3", i1.B(12));
 8            Assert.AreEqual(String.Empty, i1.A);
 9
10            ClassB b = new ClassB();
11            ClassC c = new ClassC();
12            TInterface i2 = TypeTemplate.Create<TInterface>(b, c);
13            Assert.AreNotEqual(null, i2);
14            Assert.AreEqual("3", i2.B(12));
15            Assert.AreEqual(String.Empty, i2.A);
16        }

17

 

三、说明:

(1)通过上述方法可以很方便的创建对现有实例的Wrapper,使其适应一个新的接口;

(2)TypeTemplate.Create<TInterface>(params Object[] impleInstances) 排位在前的 impleInstance 的接口方法/属性将掩盖它后面的 impleInstance 的接口方法/属性,这样可以在运行时动态改变接口的行为。

(3)这种MixIn方案比不上动态语言的MixIn,主要是必须要有一个interface,才能MixIn。如果能将interface也根据被代理的对象的行为动态生成,那就很爽了。怎么实现,是一个问题。

posted @ 2009-02-01 15:09  xiaotie  阅读(3016)  评论(6编辑  收藏  举报