万字详文:微软 VSCode IDE 源码分析揭秘( 三 )


}
}
Service这里通过 createService 创建一些基础的 Service
运行环境服务 EnvironmentServicesrc/vs/platform/environment/node/environmentService.ts
通过这个服务获取当前启动目录 , 日志目录 , 操作系统信息 , 配置文件目录 , 用户目录等 。
日志服务 MultiplexLogServicesrc/vs/platform/log/common/log.ts
默认使用控制台日志 ConsoleLogMainService其中包含性能追踪和释放信息 , 日志输出级别
配置服务 ConfigurationServicesrc/vs/platform/configuration/node/configurationService.ts
从运行环境服务获取内容
生命周期服务 LifecycleServicesrc/vs/platform/lifecycle/common/lifecycleService.ts
监听事件 , electron app 模块 比如:ready ,window-all-closed , before-quit
可以参考官方electron app 文档
状态服务 StateServicesrc/vs/platform/state/node/stateService.ts
通过 FileStorage 读写 storage.json 存储 , 里记录一些与程序运行状态有关的键值对
请求服务 RequestServicesrc/vs/platform/request/browser/requestService.ts
这里使用的是原生 ajax 请求 , 实现了 request 方法
主题服务 ThemeMainServicesrc/vs/platform/theme/electron-main/themeMainService.ts
这里只设置背景颜色 , 通过 getBackgroundColor 方法 IStateService 存储
签名服务 SignServicesrc/vs/platform/sign/node/signService.ts
private createServices(args: ParsedArgs, bufferLogService: BufferLogService): [IInstantiationService, typeof process.env] {
//服务注册容器
const services = new ServiceCollection();
const environmentService = new EnvironmentService(args, process.execPath);
const instanceEnvironment = this.patchEnvironment(environmentService); // Patch `process.env` with the instance's environment
services.set(IEnvironmentService, environmentService);
const logService = new MultiplexLogService([new ConsoleLogMainService(getLogLevel(environmentService)), bufferLogService]);
process.once('exit', () => logService.dispose());
//日志服务
services.set(ILogService, logService);
//配置服务
services.set(IConfigurationService, new ConfigurationService(environmentService.settingsResource));
//生命周期
services.set(ILifecycleService, new SyncDescriptor(LifecycleService));
//状态存储
services.set(IStateService, new SyncDescriptor(StateService));
//网络请求
services.set(IRequestService, new SyncDescriptor(RequestService));
//主题设定
services.set(IThemeMainService, new SyncDescriptor(ThemeMainService));
//签名服务
services.set(ISignService, new SyncDescriptor(SignService));
return [new InstantiationService(services, true), instanceEnvironment];
}
4.实例化服务SyncDescriptor 负责注册这些服务 , 当用到该服务时进程实例化使用
src/vs/platform/instantiation/common/descriptors.ts
export class SyncDescriptor {
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 方法调用 invokeFunction.get 实例化服务
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;
}
});
get 方法调用_getOrCreateServiceInstance , 这里第一次创建会存入缓存中下次实例化对象时会优先从缓存中获取对象 。
src/vs/platform/instantiation/common/instantiationService.ts
invokeFunction(fn: (accessor: ServicesAccessor, ...args: TS) => R, ...args: TS): R {
let _trace = Trace.traceInvocation(fn);
let _done = false;
try {
const accessor: ServicesAccessor = {
get: (id: ServiceIdentifier, 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
}
return result;
}
};
return fn.apply(undefined, [accessor, ...args]);
} finally {
_done = true;
_trace.stop();
}
}
private _getOrCreateServiceInstance(id: ServiceIdentifier, _trace: Trace): T {