Visitar URL original
Allow for easier debug of dependency graph · Issue #960 · joist-framework/joist · GitHub
Skip to content

Allow for easier debug of dependency graph  #960

Open

Description

@deebloo

To help make it easier to debug injectors and their dependencies there should be an optional API that will describe how a particular series was resolved.

Initial thought it is export an additional injectDebug() function. (To make it tree shakeable)

This function would log the dependency tree for the injected service.

Cc @Phoscur

Activity

  1. Phoscur commented on May 5, 2024

    @Phoscur
    Contributor

    Initial thought it is export an additional injectDebug() function. (To make it tree shakeable)

    That sounds easiest to maintain, but it might be limited by or breaking encapsulation in places?

    Replacing the implementation of entire core files would be a potential alternative I've seen in other projects. Applying that here it would mean: Copy injector.ts: injector.debug.ts, sprinkle in many console.debug statements or save debug info into arrays to be inspected later ... e.g. especially where undefined is returned. Although it is worse to maintain (code duplication), it does not tempt you to break encapsulation or rather gives you full freedom of debuggability.

  2. deebloo commented on May 5, 2024

    @deebloo
    MemberAuthor

    Another though would be to add the ability to pass a debug function to inject(). Inject(Service, { debug })

  3. Phoscur commented on May 18, 2024

    @Phoscur
    Contributor

    One debugging usecase, counting instances:

    // in some element:
    static providers = [{ provide: EconomyService, use: EconomyService }]; // force a new instance for each element
    
    // then I need to decorate my service like this to debug the amount of actual instances created (and alive?!):
    @injectable
    export class EconomyService {
      static count = 0;
      constructor() {
        EconomyService.count++;
        console.log('E', EconomyService.count);
      }
    }
  4. deebloo commented on Oct 30, 2024

    @deebloo
    MemberAuthor

    I wonder if another way of handling this is allowing someone to define rules around services. For example if you only ever want there to be a single instance of a particular service from some specific root. can we just throw an error

  5. matthew-salerno commented on Jul 3, 2026

    @matthew-salerno
    Contributor

    Giving this some thought because I'm noticing some strange behavior in the DOM Injector and can't quite wrap my head around whether it's correct or not without having better debugging tools. How would we feel about instead of providing a debugger function, we provide a debugger service? Injectors would try to inject this service. If they fail then everything proceeds without the debugger (pending #1406 for optional, or it could just catch the thrown errors). But if it succeeds, the injector will provide debug information to the debugger service. The debugger service collects this information and does something with it.

    First step would be just deciding on what information we care about for an API:

    1. What information should injectors give to the debugger.
    2. What information the should the debugger be able to query from injectors.

    The first debugger implementation could just log everything. In the future this could be expanded with useful features like printing the full injection tree (as a singleton, it could have access to all injectors even if they're disjoint) or providing APIs to debugging tool extensions (something like joist devtools seems very far off, but one can dream).
    Usage could look something like this:

    import {LoggingDebugger} from @joist/debug;
    import {INJECTOR_DEBUGGER} from @joist/di;
    const rootInjector = new Injector({providers: [INJECTOR_DEBUGGER, {use: LoggingDebugger}];

    Then everything from there on will print debug information. I'm not sure what the API in particular would look like, would probably take some trial and error. InjectionDebugger itself could be a minimal token for an interface. Then all the implementations should be tree shakeable or could live in a separate package entirely.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions