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

简介:

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

一、应用场景

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

复制代码
 1      public   interface  TInterface
 2 ExpandedBlockStart.gif     {
 3ExpandedSubBlockStart.gif        String A get; }
 4        String B(int a, int b);
 5    }

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

15            set
16ExpandedSubBlockStart.gif            { }
17        }

18    }

19
20      public   class  ClassC
21 ExpandedBlockStart.gif     {
22        public String B(int a, int b)
23ExpandedSubBlockStart.gif        {
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 ExpandedBlockStart.gif     {
 3        String Heart();
 4        String Lung();
 5        String Name();
 6    }

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

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

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

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

32
33        static void Main(string[] args)
34ExpandedSubBlockStart.gif        {
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    }
复制代码

 

输出为:

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

 

二、实现

以下是详细实现代码:

 

ContractedBlock.gif Code

 

测试代码:

复制代码
 1         [TestMethod]
 2          public   void  TestCreate()
 3 ExpandedBlockStart.gif         {
 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也根据被代理的对象的行为动态生成,那就很爽了。怎么实现,是一个问题。

本文转自xiaotie博客园博客,原文链接http://www.cnblogs.com/xiaotie/archive/2009/02/01/1381973.html如需转载请自行联系原作者


xiaotie 集异璧实验室(GEBLAB)

相关文章
|
4月前
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
46 0
|
16天前
|
开发框架 前端开发 JavaScript
JavaScript云LIS系统源码ASP.NET CORE 3.1 MVC + SQLserver + Redis医院实验室信息系统源码 医院云LIS系统源码
实验室信息系统(Laboratory Information System,缩写LIS)是一类用来处理实验室过程信息的软件,云LIS系统围绕临床,云LIS系统将与云HIS系统建立起高度的业务整合,以体现“以病人为中心”的设计理念,优化就诊流程,方便患者就医。
22 0
|
2月前
|
开发框架 前端开发 .NET
进入ASP .net mvc的世界
进入ASP .net mvc的世界
32 0
|
2月前
mvc.net分页查询案例——mvc-paper.css
mvc.net分页查询案例——mvc-paper.css
5 0
|
2月前
|
开发框架 前端开发 .NET
C# .NET面试系列六:ASP.NET MVC
<h2>ASP.NET MVC #### 1. MVC 中的 TempData\ViewBag\ViewData 区别? 在ASP.NET MVC中,TempData、ViewBag 和 ViewData 都是用于在控制器和视图之间传递数据的机制,但它们有一些区别。 <b>TempData:</b> 1、生命周期 ```c# TempData 的生命周期是短暂的,数据只在当前请求和下一次请求之间有效。一旦数据被读取,它就会被标记为已读,下一次请求时就会被清除。 ``` 2、用途 ```c# 主要用于在两个动作之间传递数据,例如在一个动作中设置 TempData,然后在重定向到另
110 5
|
4月前
|
XML 前端开发 定位技术
C#(NET Core3.1 MVC)生成站点地图(sitemap.xml)
C#(NET Core3.1 MVC)生成站点地图(sitemap.xml)
30 0
|
4月前
|
前端开发
.net core mvc获取IP地址和IP所在地(其实是百度的)
.net core mvc获取IP地址和IP所在地(其实是百度的)
128 0