1.7
插件式软件框架
插件式软件框架开发的核心技术是基于接口编程和程序集反射技术。接口和具体实现分离是面向组件编程的核心原则,反射是通过编程方式读取与类型相关的元数据的行为。
把接口从实现分离时,具体实现是针对服务抽象(接口)进行编程,不是一个具体的对象实现。这样,当改变接口服务的实现细节时不会影响具体实现过程。在传统的面向对象编程中,通常使用抽象类来定义一个服务抽象。抽象类用来定义一套协议,多个从抽象类中派生出来的类将实现这些协议。当不同的服务提供程序共享一个公共基类时,它们将成为服务抽象的多态,客户端只需要很少的改变就能够在不同的服务提供程序之间进行切换。不过,抽象类和接口之间有如下几个重要的不同之处。
(1)一个抽象类仍然可以有实现,它有成员变量、抽象方法或属性,而接口不能实现具体的过程,也不能有成员变量。
(2)一个.NET类只能从一个基类中派生,即便基类是抽象的。然而,一个.NET类可以根据需要实现多个接口。
(3)抽象类可以从其他类或从一个或多个接口中派生,而接口只能从另一接口派生。
(4)抽象类可以有静态方法和静态成员,同时能定义常量,而接口可以不包含其中任何一个。
(5)抽象类可以有构造函数,而接口不可以。
抽象类和接口之间的差异是刻意设计出来的,并不是为了限制接口的使用,而是为了在服务提供程序(实现接口的类)和服务使用程序(类的客户端)之间提供一个正式的公共契约。不允许在接口中实现任何细节,如方法、常量、静态成员和构造函数等,可以使.NET进一步促进服务提供者与客户端的松散耦合。因为契约中没有任何实现,所以具体实现在接口设计完成之后。接口起到了组件之间隔离的作用,从而实现结构化框架设计的模块化。
定义和实现一个接口的代码如下。
反射是通过编程方式读取与类型相关联的元数据的行为,通过读取元数据,能了解它是什么类及它由什么构成(即方法、属性和基类)。反射服务在System.Reflection命名空间中定义,System命名空间中定义抽象类Type,.NET类中提供的所有类型(数值、类和接口),还有开发人员定义的类型,都有相应且唯一的Type值,为反射提供了基础操作的媒介。反射还有另一个特性,即通过Emit操作可以在程序运行期间定义新类型,生成相应的IL代码和元数据,代码如下。
软件框架是使用接口和反射技术实现的插件机制,在后面的章节中将进行详细介绍。