但是随着.NET的设计师开始规划新的应用程序和应用场合,向下一代结构(例如,Web服务)的迁移意味着越来越多的应用程序将是纯.NET的应用程序,在最终取代COM之前,它们只需要同原有的COM程序进行相互操作就行了。在开发和部署.NET应用程序的过程中,实现两者间的无缝相互操作应该是应用程序设计者的重点之一。现在让我们看一些需要考虑的关键问题。
当一个正在运行的.NET应用程序要调用一个COM对象的时候,CLR会在可管理的.NET代码和自由的COM代码之间生成一个代理,叫做运行可调用包装器(runtime
callable wrapper,RCW)。CLR会使用一个interop组件作为其生成RCW的蓝图。Interop组件只定义原有COM组件里的类型,而且不具有实现代码。所生成的RCW允许可管理代码在编译的时候绑定到COM组件的类型上,并向CLR给出信息,提示其在运行期间类型应该被如何封送处理(marshal)。
由于.NET应用程序需要使用interop组件来让CLR生成正确的RCW,所以你必须确信这些组件在开发阶段和部署之后能够在你的程序里使用。当然,任何.NET应用程序所使用的COM程序仍然必须在计算机(组件)里注册,或者正确地安装在COM+目录(也就是说COM+开发包)里。
在开发.NET应用程序的过程中,Visual Studio .NET会自动地创建所需要的interop组件。当你向原有的COM程序添加参考(reference)的时候,VS.NET会创建一个允许你调用这个COM程序的interop组件。而VS.NET使用的是替换(alternative)interop组件而不是主(primary)interop组件。这一点很重要,因为主interop组件在类型库里有类型的官方的和特征性的(signed)定义,而替换interop组件有无特征性(unsigned)类型的版本。此外,如果两个应用程序互相传递COM对象,那么CLR会生成一个类型不匹配的异常,这其中一个RCW要根据主interop组件,而另一个要根据替换interop组件。为了保险起见,在开发的过程中,你应该总是使用主interop组件。
要做到这一点,你应该使用组件发布器所提供的主interop组件(在由第三方组件的情况下),或者生成你自己的主interop组件,用在你内部开发的COM对象上。你应该使用类型库导入器(Type
Lib Importer,Tlbimp.exe),它会把COM方法的签名转换成可管理签名。要让interop组件成为主interop组件,你必须指定主开关“/”,并给组件标上。一旦被创建,你就要使用Regasm在开发人员的系统上注册这个组件和主interop组件,并把主interop组件放入进行开发的计算机的全局组件缓冲区里。这一步能够让你在任何进行开发的计算机上使用这个COM组件。更重要的是,当你把参照设置到COM组件上的时候,VS.NET会检测主interop组件是否存在,如果存在的话就会使用它,而不是创建一个替换interop组件。
如果你正确配置了开发环境,那么部署使用.NET原有程序的.NET应用程序是很简单的。主要的不同点是,主interop组件不需要在部署系统上注册。在进行开发的计算机上进行注册的原因是要通知VS.NET已经存在一个主interop组件了。
在部署系统上,你只需要简单地把主interop组件放到全局组件缓冲区(Global Assembly Cache,GAC),或者将其和应用程序的其他代码一起放在一个私有的应用程序目录下。如果COM组件要被同一个系统上的多个应用程序使用,你就应该把主interop组件放在GAC里,这样会让未来的升级更容易。