VSCode源码分析 - 实例化服务

目录

实例化服务

SyncDescriptor负责注册这些服务,当用到该服务时进程实例化使用

src/vs/platform/instantiation/common/descriptors.ts

  1. export class SyncDescriptor<T> {
  2. readonly ctor: any;
  3. readonly staticArguments: any[];
  4. readonly supportsDelayedInstantiation: boolean;
  5. constructor(ctor: new (...args: any[]) => T, staticArguments: any[] = [], supportsDelayedInstantiation: boolean = false) {
  6. this.ctor = ctor;
  7. this.staticArguments = staticArguments;
  8. this.supportsDelayedInstantiation = supportsDelayedInstantiation;
  9. }
  10. }

main.ts中startup方法调用invokeFunction.get实例化服务

  1. await instantiationService.invokeFunction(async accessor => {
  2. const environmentService = accessor.get(IEnvironmentService);
  3. const configurationService = accessor.get(IConfigurationService);
  4. const stateService = accessor.get(IStateService);
  5. try {
  6. await this.initServices(environmentService, configurationService as ConfigurationService, stateService as StateService);
  7. } catch (error) {
  8. // Show a dialog for errors that can be resolved by the user
  9. this.handleStartupDataDirError(environmentService, error);
  10. throw error;
  11. }
  12. });

get方法调用_getOrCreateServiceInstance,这里第一次创建会存入缓存中 下次实例化对象时会优先从缓存中获取对象。

src/vs/platform/instantiation/common/instantiationService.ts

  1. invokeFunction<R, TS extends any[] = []>(fn: (accessor: ServicesAccessor, ...args: TS) => R, ...args: TS): R {
  2. let _trace = Trace.traceInvocation(fn);
  3. let _done = false;
  4. try {
  5. const accessor: ServicesAccessor = {
  6. get: <T>(id: ServiceIdentifier<T>, isOptional?: typeof optional) => {
  7. if (_done) {
  8. throw illegalState('service accessor is only valid during the invocation of its target method');
  9. }
  10. const result = this._getOrCreateServiceInstance(id, _trace);
  11. if (!result && isOptional !== optional) {
  12. throw new Error(`[invokeFunction] unknown service '${id}'`);
  13. }
  14. return result;
  15. }
  16. };
  17. return fn.apply(undefined, [accessor, ...args]);
  18. } finally {
  19. _done = true;
  20. _trace.stop();
  21. }
  22. }
  23. private _getOrCreateServiceInstance<T>(id: ServiceIdentifier<T>, _trace: Trace): T {
  24. let thing = this._getServiceInstanceOrDescriptor(id);
  25. if (thing instanceof SyncDescriptor) {
  26. return this._createAndCacheServiceInstance(id, thing, _trace.branch(id, true));
  27. } else {
  28. _trace.branch(id, false);
  29. return thing;
  30. }
  31. }