目前的讨论主要集中在MSCOREE.DLL如何确定加载哪个CLR DLL。而如何指示MSCOREE.DLL执行它我们已经讨论过了。
MSCOREE.DLL的使用方式多种多样。托管的可执行文件隐式地在PE/COFF头中引用MSCOREE.DLL。特别是,托管的.EXE可以将Win32级的主入口点转移到SCOREE的CorExeMain。在加载CLR之后,_CorExeMain简单地遍历程序的元数锯.并执行程序的CLR级的主入口点。
同样,DLL程序由它们的Win32级主入口点转移到_CorExeMain。不管哪种情况,MSCOREE.DLL都将在执行代码的主入口点之前把执行模式由非托管变为托管模式。
为了维护COM的兼容性,MSCOREE.DLL也导出DLLGetClassObject。当MSCOREE.DLL被注册为InteropServices时,MSCOREE.DLL期望找到附加的注册项,用于标明程序集和对应COM类的类型名。REGASM.EXE工具可以自动写入这些内容。例如,考察下面的c#类:
using System.Runtime.InteropServices;
namespace AcmeCorp.Utilities{
[Guid(“2bb710e9-7cf0-46fa-91fe-94e46f44a76a”)]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IOPener{void Open();}
[Guid(“5321aeb6-2a7d-43f1-a045-2392eb917f73”)]
public class Pliers:IOpener{
public void Open(){}
}
}
这个类将导致REGASM.EXE产生下面的注册项:
注意,Class和Assembly指定目标类的完全限定名。此外,还要注意CodeBase注册项,它提供了被程序集解析器使用的必要codebase(基本代码)提示。这个codebase提示很关键,因为COM客户端将没有它自已的配置文件。只有通过指定/codebase命令选项,执行REGASM.EXE才能将codebase提示插入到注册表中。
你还可以通过COM+l.x目录管理器(COM+l.x catalog manager)注册一个基于CLR的类型。基于CLR的类型如果要以COM+进行配置,则必须直接或者间接地继承System.EnterpriseServices.ServicedComponent基类型。这个基类型确保基于CLR对象具有COM+l.x上下文与之关联。对于CLR第1版,COM+l.x服务仍然是通过非托管的COM代码实现的ServicedComponent的使用相当于CLR的标志,用于确保CLR和COM+l.x上下文对新对象都有效、当CLR创建服务组件的实例时,它要确保对于这个类有适合的COM+l.x目录项。为此,绝人多数COM+l.x目录特性作为元数据特性是有效的,它们允许开发人员在开发时(development time),指定他们的COM+1.x服务需求。
最后,为了避免使用COM interop,CLR通过Systme.Enterprise Services.Context.Util类型,使CoGetObjectContext工具有效。截止到本书写作时,COM+l.x为了保证这种管道(plumbing)的使用,其独有的特征使运用分布式事务协作(distributed transaction coordinator,DTC)更为简便。当然,不需要DTC的应用程序可能也不会需要COM+1.x。要获得更多的内容,可以参见Tim Ewald的专著《Transactional COM+》(Addison-Wesley, 2001)。