vscode源码分析【六】服务实例化和单例的实现

第一篇: vscode源码分析【一】从源码运行vscode
第二篇:vscode源码分析【二】程序的启动逻辑,第一个窗口是如何创建的
第三篇:vscode源码分析【三】程序的启动逻辑,性能问题的追踪
第四篇:vscode源码分析【四】程序启动的逻辑,最初创建的服务
第五篇:vscode源码分析【五】事件分发机制

细心的读者可能会发现,在第四篇文章中的createService方法中,并没有把所有的服务实例化,下面这些服务,只是记了他们的类型:
src\vs\code\electron-main\main.ts

		services.set(ILifecycleService, new SyncDescriptor(LifecycleService));
		services.set(IStateService, new SyncDescriptor(StateService));
		services.set(IRequestService, new SyncDescriptor(RequestService));
		services.set(IDiagnosticsService, new SyncDescriptor(DiagnosticsService));
		services.set(IThemeMainService, new SyncDescriptor(ThemeMainService));
		services.set(ISignService, new SyncDescriptor(SignService));

SyncDescriptor负责记录这些服务的类型,以供后续使用
(src\vs\platform\instantiation\common\descriptors.ts)

export class SyncDescriptor<T> {
	readonly ctor: any;
	readonly staticArguments: any[];
	readonly supportsDelayedInstantiation: boolean;
	constructor(ctor: new (...args: any[]) => T, staticArguments: any[] = [], supportsDelayedInstantiation: boolean = false) {
		this.ctor = ctor;
		this.staticArguments = staticArguments;
		this.supportsDelayedInstantiation = supportsDelayedInstantiation;
	}
}

接下来,main.ts的startup方法内,就实例化了这些服务

			await instantiationService.invokeFunction(async accessor => {
				const environmentService = accessor.get(IEnvironmentService);
				const configurationService = accessor.get(IConfigurationService);
				const stateService = accessor.get(IStateService);
				try {
					await this.initServices(environmentService, configurationService as ConfigurationService, stateService as StateService);
				} catch (error) {

					// Show a dialog for errors that can be resolved by the user
					this.handleStartupDataDirError(environmentService, error);

					throw error;
				}
			});

这里accessor的get方法如下:(src\vs\platform\instantiation\common\instantiationService.ts)

				get: <T>(id: ServiceIdentifier<T>, isOptional?: typeof optional) => {

					if (_done) {
						throw illegalState('service accessor is only valid during the invocation of its target method');
					}

					const result = this._getOrCreateServiceInstance(id, _trace);
					if (!result && isOptional !== optional) {
						throw new Error(`[invokeFunction] unknown service '${id}'`);
					}
					return result;
				}

有个_getOrCreateServiceInstance方法:

	private _getOrCreateServiceInstance<T>(id: ServiceIdentifier<T>, _trace: Trace): T {
		let thing = this._getServiceInstanceOrDescriptor(id);
		if (thing instanceof SyncDescriptor) {
			return this._createAndCacheServiceInstance(id, thing, _trace.branch(id, true));
		} else {
			_trace.branch(id, false);
			return thing;
		}
	}

你发现,如果它想获取的对象是SyncDescriptor类型的,就会创建并缓存相应的对象
这个方法_createAndCacheServiceInstance负责创建对象的实例(暂时先不解释)
下次获取这个对象的时候,就直接从缓存中获取了
 

posted @ 2019-06-19 10:38  liulun  阅读(1230)  评论(0编辑  收藏  举报