当前位置: 首页 > news >正文

青岛营销型网站建设网站建设页面图

青岛营销型网站建设,网站建设页面图,一站式网站开发,嘉兴网站建设嘉兴网站推广在上一篇介绍了 VSCode 的依赖注入设计#xff0c;并且实现了一个简单的 IOC 框架。但是距离成为一个生产环境可用的框架还差的很远。 行业内已经有许多非常优秀的开源 IOC 框架#xff0c;它们划分了更为清晰地模块来应对复杂情况下依赖注入运行的正确性。 这里我将以 Inv…在上一篇介绍了 VSCode 的依赖注入设计并且实现了一个简单的 IOC 框架。但是距离成为一个生产环境可用的框架还差的很远。 行业内已经有许多非常优秀的开源 IOC 框架它们划分了更为清晰地模块来应对复杂情况下依赖注入运行的正确性。 这里我将以 InversifyJS 为例分析它的生命周期设计来弄清楚在一个优秀的 IOC 框架中完成一次注入流程到底是什么样的。 InversifyJS 的生命周期 在激活 InversifyJS 后框架通常会监听并经历五个阶段分别是 Annotation 注释阶段Planning 规划阶段Middleware (optional) 中间件钩子Resolution 解析执行阶段Activation (optional) 激活钩子 本篇文章将着重介绍其中的三个必选阶段。旨在解释框架到底是如何规划模块实例化的先后顺序以实现依赖注入能力的。 接下来的解析将围绕如下例子 injectable()class FooBar implements FooBarInterface {public foo : FooInterface;public bar : BarInterface;constructor(inject(FooInterface) foo: FooInterface, inject(BarInterface) bar: BarInterface) {this.foo foo;this.bar bar;}}const container new Container();const foobar container.getFooBarInterface(FooBarInterface);Annotation 注释阶段 在此阶段中框架将通过装饰器为所有接入框架的对象打上标记以便规划阶段时进行管理。 在这个阶段中最重要的 API 就是 injectable 。它使用 Reflect metadata对 Class 构造函数中通过 inject API 注入的 property 进行标注并挂在在了该类的 metadataKey 上。 function injectable() {return function(target: any) {if (Reflect.hasOwnMetadata(METADATA_KEY.PARAM_TYPES, target)) {throw new Error(ERRORS_MSGS.DUPLICATED_INJECTABLE_DECORATOR);}const types Reflect.getMetadata(METADATA_KEY.DESIGN_PARAM_TYPES, target) || [];Reflect.defineMetadata(METADATA_KEY.PARAM_TYPES, types, target);return target;}; }Planning 规划阶段 本阶段时该框架的核心阶段它真正生成了在一个 Container 中所有类模块的依赖关系树。因此在 Container 类进行实例化时规划阶段就开始了。 在实例化时根据传入的 id 与 scope 可以确定该实例容器的作用域范围生成一个 context拥有对内左右模块的管理权。 class Context implements interfaces.Context {public id: number;public container: interfaces.Container;public plan: interfaces.Plan;public currentRequest: interfaces.Request;public constructor(container: interfaces.Container) {this.id id(); // generate a unique idthis.container container;}public addPlan(plan: interfaces.Plan) {this.plan plan;}public setCurrentRequest(currentRequest: interfaces.Request) {this.currentRequest currentRequest;} }我们可以注意到这个 context 中包含一个空的 plan 对象这是 planning 阶段的核心该阶段就是为生成的容器规划好要执行的任务。 plan 对象中将包含一个 request 对象request 是一个可递归的属性结构它包含了要查找的 id 外还需要 target 参数即规定找到依赖实例后将引用赋值给哪个参数。 class Request implements interfaces.Request {public id: number;public serviceIdentifier: interfaces.ServiceIdentifierany; // 被修饰类 idpublic parentContext: interfaces.Context;public parentRequest: interfaces.Request | null; // 树形结构的 request指向父节点public bindings: interfaces.Bindingany[];public childRequests: interfaces.Request[]; // 树形结构的 request指向子节点public target: interfaces.Target; // 指向赋值目标参数public requestScope: interfaces.RequestScope;... }以篇头的例子为例。在容器执行 get 函数后框架生成了一个新的 plan该 plan 的生成过程中将执行_createSubRequests 方法从上而下创建 Request 依赖树。 创建完成后的 plan 对象生成的 request 树将包含有请求目标为 null 的根 request 与两个子 request 第一个子 request 指向 FooInterface 接口并且请求结果的 target 赋值给构造函数中的参数 foo。第二个子 request 指向 BarInterface 接口并且请求结果的 target 赋值给构造函数中的参数 bar。 注意此处的依赖树生成仍在 interface 层面没有任何类被实例化。 用一张图来更直观地表现该阶段中各对象的生成调用过程 这样每一个类与其依赖项之间的请求关系就构造完毕了。 Resolution 解析执行阶段 该阶段便是执行在规划阶段中生成的 request 依赖树从无依赖的叶子节点开始自下而上实例化每一个依赖类到根 request 结束时即最终完成 FooBar 自身的实例化。 且该解析过程可以选择同步或异步执行在复杂情况下使用异步懒加载的方式执行解析有助于提高性能。 至此一次完整的具有依赖的类的实例化就完成了。我们可以通过打印依赖树清晰地观察到该实例依赖了哪些实例从而避免了一切可能的循环依赖与多次构造依赖带来的内存泄露等很多难以排查的问题。 参考资料 InversifyJS Architecture Overview
http://www.w-s-a.com/news/261353/

相关文章:

  • 音乐网站建设目标合同管理系统
  • jq网站特效插件如何知道网站是否被k
  • 自己的网站怎么接广告网站搭建收费
  • 宁波大型网站制作建立一个网站 优帮云
  • 大连零基础网站建设教学电话有哪些比较好的做ppt好的网站
  • 哪个网站做logo设计我的建筑网
  • php电子商务网站开发沂源手机网站建设公司
  • html和php做网站哪个好3gcms企业手机网站整站源码asp
  • 网站建设网页设计案例云南建设厅网站删除
  • 杏坛网站制作太原做网站要多少钱呢
  • 做新闻类网站还有市场吗东莞黄页网广告
  • 地方网站做外卖专业做互联网招聘的网站有哪些
  • 网站推广公司兴田德润紧急网页升级紧急通知
  • 厦门做网站哪家强企业网站网页设计的步骤
  • 普拓网站建设济南行业网站建设
  • 燕郊 网站开发网站里的地图定位怎么做
  • 门户网站建设招标互联网创业项目概述
  • 用什么做网站比较好市场调研公司是做什么的
  • 电商网站充值消费系统绍兴网站优化
  • 深圳网站建设公司联虚拟币交易网站开发
  • 专业网站设计建设公司抖音代运营公司排名前十强
  • 做网站架构肃北蒙古族自治县建设局网站
  • 推广网站怎么建经济研究院网站建设方案
  • 网站建设商家淘宝客自建网站做还是用微信qq做
  • django做网站效率高吗涉县移动网站建设报价
  • 做外贸网站注册什么邮箱能够做渗透的网站
  • 购物网站 怎么做织梦网站会员功能
  • 北京市网站开发公司郑州联通网站备案
  • 温岭专业营销型网站建设地址wordpress小程序怎么不用认证审核
  • 网站建设主体设计要求微信公众号缴费