上层设计
- rpc通信
- 进行(主进程,渲染进程,插件进程)
- vscode如何暴露给插件
- 插件的设计
运行时的设计
- Service模式
- 依赖注入
一些设计
- event设计
- TreeContext设计
一些重点Service
- ListService
- IInstantiationService
- CommandService
typescript的用法
- 装饰器
优秀的设计
- 程序的健壮性(interface)
- 程序的复用和扩展性(TreeView)
一些反思和质疑
- 这种面向对象渲染模式是否好?写起来效率太低了
上层设计
rpc通信
进程管理
vscode如何暴露给插件
插件的设计
运行时设计
Service模式
看下fileAction中使用到service和accesor的
// 获取explorerContext
function getContext(listWidget: ListWidget, viewletService: IViewletService): IExplorerContext {
// These commands can only be triggered when explorer viewlet is visible so get it using the active viewlet
const tree = <ITree>listWidget;
const stat = tree.getFocus();
const selection = tree.getSelection();
// Only respect the selection if user clicked inside it (focus belongs to it)
return { stat, selection: selection && selection.indexOf(stat) >= 0 ? selection : [], viewletState: (<ExplorerViewlet>viewletService.getActiveViewlet()).getViewletState() };
}
// 注册新建文件的命令,右键会通过commandService调用此命令
CommandsRegistry.registerCommand({
id: NEW_FILE_COMMAND_ID,
handler: (accessor) => {
return openExplorerAndRunAction(accessor, NewFileAction);
}
});
// 新建文件时的处理逻辑
function openExplorerAndRunAction(accessor: ServicesAccessor, constructor: IConstructorSignature2<ITree, ExplorerItem, Action>): TPromise<any> {
const instantationService = accessor.get(IInstantiationService);
const listService = accessor.get(IListService);
const viewletService = accessor.get(IViewletService);
const activeViewlet = viewletService.getActiveViewlet();
let explorerPromise: Thenable<IViewlet> = Promise.resolve(activeViewlet);
if (!activeViewlet || activeViewlet.getId() !== VIEWLET_ID) {
explorerPromise = viewletService.openViewlet(VIEWLET_ID, true);
}
return explorerPromise.then((explorer: ExplorerViewlet) => {
const explorerView = explorer.getExplorerView();
if (explorerView && explorerView.isVisible() && explorerView.isExpanded()) {
explorerView.focus();
//
const explorerContext = getContext(listService.lastFocusedList, viewletService);
const action = instantationService.createInstance(constructor, listService.lastFocusedList, explorerContext.stat);
return action.run(explorerContext);
}
return undefined;
});
}
```
ServicesAccessor?
就像window的全局变量,供我们来访问各种service。在command回调参数中有个accesor。
Service模式?
是什么,特征?哪些服务该设计成service?设计有何益处,即如果没有呢?
- 是什么?
特征和使用
全局的只有一个实例,command会掉参数有个accesor参数,可以通过accesor获取到唯一的service。
哪些服务该设计成service
设计的益处和原因?
依赖注入可以注入service
如果不用service模式呢?
依赖注入
为什么需要依赖注入?TODO
依赖注入的实现
- 类实例化时都通过
instantiationService.createInstance(Clazz)
初始化 - construcrot上通过@符号,标记需要注入的service
一些重点Service
IInstantiationService
依赖注入的实现
所有实例化都通过调用此的createInstance方法来进行实例化。
因为需要依赖注入,初始化前检查constructor上的注入标记。
src/vs/platform/instantiation/common/instantiationService.ts
见此文件
ServicesAccessor
访问所有的service,在command的回调参数中
CommandService
命令
ListService
所有list都注册在这里,可获取最后active的list
ViewletService
一些设计
事件设计
TreeContext
Typescript应用
优秀的设计
程序的健壮性
所有都用interface进行了定义,类定义,参数定义等等。
只要写的有问题就会报错
程序的复用和扩展性
TreeView将逻辑暴露给Context
ViewItem将内容渲染交给renderer
一些质疑和思考
这种面向对象渲染模式是否好?
修改有点太复杂了
渲染很多都是局部更新,添加class等,局部状态?