代码改变世界

[转载]AAF灵便应用框架简介系列(2):AAF应用的启动和初始化

2009-04-02 09:28  周国选  阅读(525)  评论(0编辑  收藏  举报

一个典型AAF应用由如下几个部分组成:
1)一组配置文件,其中最基本的是Boot.Config,通过该文件声明应用所需要的各服务接口及其实现
2)AAF基本服务定义及其实现Assembly/程序集
3)应用自定义的服务定义及其实现Assembly/程序集
4)一个恰当的服务集加载点。一般来说,Web应用应该在Application.OnStart实践处理方法中直接或间接调用Aaf.Core.ServiceHub.Init(false);Windows应用则应该在Main方法中直接或间接调用前述方法。

下面我们稍作展开,对Boot.Config以及AAF应用的启动过程进行较为详细的介绍。
我们首先看一下一个典型的Boot.Config文件:
<?xml version="1.0" encoding="utf-8" ?>
<Boot>
 <Services>
  <Service Type="Aaf.Agile.ITypeService, Aaf.Agile" Driver="Aaf.Agile.Imp.TypeService, Aaf.Agile.Imp"/>
  <Service Type="Aaf.Persistence.IStorageContextMappingService, Aaf.Persistence" Driver="Aaf.Persistence.Imp.StorageContextMappingService, Aaf.Persistence.Imp"/>
  <Service Type="Aaf.Persistence.IPersistenceMappingService, Aaf.Persistence" Driver="Aaf.Persistence.Imp.PersistenceMappingService, Aaf.Persistence.Imp"/>
  <Service Type="Aaf.Persistence.IPersister, Aaf.Persistence" Driver="Aaf.Persistence.Imp.Persister, Aaf.Persistence.Imp"/>
  <Service Type="Aaf.Persistence.IAgileObjectXmlService, Aaf.Persistence" Driver="Aaf.Persistence.Imp.AgileObjectXmlService, Aaf.Persistence.Imp"/>
  <Service Type="Aaf.Storage.IStorageService, Aaf.Storage" Driver="Aaf.Storage.Imp.StorageService, Aaf.Storage.Imp"/>
  <Service Type="Aaf.Core.ICacheService, Aaf.Core" Driver="Aaf.Cache.Imp.CacheService, Aaf.Cache.Imp"/>
  <Service Type="Aaf.Core.IConfigurationService, Aaf.Core" Driver="Aaf.Core.Imp.ConfigurationService, Aaf.Core.Imp"/>
  <Service Type="Aaf.Core.IApplicationService, Aaf.Core" Driver="Aaf.Core.Imp.ApplicationService, Aaf.Core.Imp"/>
  <Service Type="Aaf.Core.ITimeStampService, Aaf.Core" Driver="Aaf.Core.Imp.TimeStampService, Aaf.Core.Imp"/>
  <Service Type="Aaf.Query.IQueryService, Aaf.Query" Driver="Aaf.Query.Imp.QueryService, Aaf.Query.Imp"/>
  <Service Type="Aaf.SyncProxy.ISyncServiceProxy, Aaf.SyncProxy" Driver="Aaf.SyncProxy.Imp.SyncServiceProxy, Aaf.SyncProxy.Imp"/>
  <Service Type="Aaf.Para.IParaService, Aaf.Para" Driver="Aaf.Para.Imp.ParaService, Aaf.Para.Imp"/>
  <Service Type="Aaf.UiHelper.IDataReaderVisualizer, Aaf.UiHelper" Driver="Aaf.UiHelper.Imp.DataReaderVisualizer, Aaf.UiHelper.Imp"/>
  <Service Type="Aaf.Org.IOrgService, Aaf.Org" Driver="Aaf.Org.Imp.OrgService, Aaf.Org.Imp"/>
  <Service Type="XX.Core.IQueryDriver, XX.Core" Driver="XX.Core.Imp.QueryDriver, XX.Core.Imp.QueryDriver"/>
  <Service Type="XX.Core.ISiteService, XX.Core" Driver="XX.Core.Imp.SiteService, XX.Core.Imp"/>
  <Service Type="XX.Core.IBizOfferService, XX.Core" Driver="XX.Core.Imp.BizOfferService, XX.Core.Imp"/>
  <Service Type="XX.Core.IUserService, XX.Core" Driver="XX.Core.Imp.UserService, XX.Core.Imp"/>
  <Service Type="XX.Core.IGameService, XX.Core" Driver="XX.Core.Imp.GameService, XX.Core.Imp"/>
  <Service Type="XX.Core.ICouponService, XX.Core" Driver="XX.Core.Imp.CouponService, XX.Core.Imp.Payment"/>
  <Service Type="XX.Core.IPaymentService, XX.Core" Driver="XX.Core.Imp.PaymentService, XX.Core.Imp.Payment"/>
  <Service Type="XX.Core.IOrderService, XX.Core" Driver="XX.Core.Imp.OrderService, XX.Core.Imp.Payment"/>
 </Services>
</Boot>

Boot.Config文件在“Boot/Services”路径下逐个定义了应用所需的各服务。每一个服务定义由Type和Driver两个属性组成。前者描述了一个服务的接口名称(包含namespace前缀以及通过逗号分割的接口所在程序集/Assembly名后缀),后者指定了该接口的实现(类似的,包含namespace前缀以及通过逗号分割的接口实现所在程序集/Assembly名后缀)。在ServiceHub.Init(false)的执行过程中,系统将根据Boot.Config的约定自动创建各服务实例并对各服务按照预定的步调进行初始化。当个服务初始化完成后,应用即进入与非AAF应用类似的正常运行阶段,所不同的该阶段的AAF应用可以通过Aaf.Core.ServiceHub.Instance.GetService()方法获得各服务实例并通过服务提供的方法、属性使用该服务提供的各种功能。在调用GetService方法时,调用方秩序传入所需服务的接口类型,而无需关心服务的实现指向。比如,如果我们想获得持久化服务,就只需如下代码:
Aaf.Persistence.IPersister persister = (Aaf.Persistence.IPersister)Aaf.Core.ServiceHub.Instance.GetService(typeof(Aaf.Persistence.IPersister));

AAF服务的基本初始化步调如下:
1)Init(调用各服务的IService.Init方法)
2)Load(调用各服务的IService.Load方法)
3)Prepare(调用各服务的IService.Prepare/PrepareInternal方法)
4)Run(调用各服务的IService.Run方法)
在第一步和第二步,服务一般不应访问其它服务(除了个别预加载服务,如日志服务:IRuntimeLogService,可以通过调用ServiceHub.AddLog方法间接调用该服务的相关方法),在Prepare阶段,服务A可以借助其它服务进行初始化,但是必须首先确保所需服务B已经成功完成Prepare(通过该服务通过IService接口提供的IsPrepared属性。这里强调一点,所有服务接口都没有集成IService,所以如果试图通过服务实现访问IService时,需要进行强制装换,如:if (((Aaf.Core.IService)persister).IsPreapred) ...)
,否则服务A必须暂时放弃Prepare的执行并在PrepareInternal方法中返回false。内核会继续尝试其它服务的初始化并在稍后重试服务A的初始化。所有服务的Prepare阶段将不断重复这一过程直到所有服务Prepare都先后在某一次调用后返回true(此时系统会自动将IsPrepared属性设置为true)或者所有可以Prepare的服务都已执行完毕只剩下几个因为不恰当的相互依赖或者其他原因总也无法Prepare的方法为止。

一旦Prepare阶段树立完成,AAF内核将进入所有服务初始化的最后阶段:Run阶段。在Run阶段,各服务可以启动本服务执行所需的守候线程或者工作线程或者完成其它服务认为应该放在此阶段的任务。

当所有的服务都完成Run阶段后,AAF的初始化阶段就彻底完成了,AAF应用进入与普通应用类似的正常运行阶段。