Can the Angular $injector be decorated with $provide.decorator?

前端 未结 2 1216
闹比i
闹比i 2020-12-30 02:13

Perhaps this is a terrible idea, but if it is then please tell me why and then pretend that it\'s an academic exercise that won\'t see the light of day in production.

2条回答
  •  -上瘾入骨i
    2020-12-30 02:56

    The answer is: no.


    $provide.decorator is used to intercept service creation -- that is why it is called from .config block, when there is still time to configure all services, as none of them has been created. $provide.decorator basically gets the Provider of the service and swaps its $get with newly delivered decorFn.

    $injector is not like other services. It is created, as the very first step of bootstrapping an application -- way before app.config is called. [look at functions: bootstrap and createInjector in angular source code]

    But hey, you can achieve your goal quite easily by tweaking the source code just a bit :-) Particularly look at function invoke(fn, self, locals).


    UPDATE I got some inspiration from @KayakDave. You actually do not have to dig in the source-code itself. You can use the following pattern to observe each call to any of $injector methods:

     app.config(['$injector', function ($injector) {
    
          $injector.proper =
          {
              get : $injector.get,
              invoke : $injector.invoke,
              instantiate : $injector.instantiate,
              annotate : $injector.annotate,
              has : $injector.has
          }
    
          function getDecorator(serviceName)
          {
              console.log("injector GET: ", serviceName);
              return this.proper.get(serviceName);
          }
    
          function invokeDecorator(fn, self, locals)
          {
              console.log("injector INVOKE: ", fn, self, locals);
              return this.proper.invoke(fn, self, locals);
          }
    
          function instantiateDecorator(Type, locals)
          {
              console.log("injector INSTANTIATE: ", Type, locals);
              return this.proper.instantiate(Type, locals);
          }
    
          function annotateDecorator (fn)
          {
              console.log("injector ANNOTATE: ", fn);
              return this.proper.annotate(fn);
          }
    
          function hasDecorator(name)
          {
              console.log("injector HAS: ", name);
              return this.proper.has(name);
          }
    
          $injector.get = getDecorator;
          $injector.invoke = invokeDecorator;
          $injector.instantiate = instantiateDecorator;
          $injector.annotate = annotateDecorator;
          $injector.has = hasDecorator;
      }]);
    

    PLNKR

提交回复
热议问题