When integrating with Angular’s DI and reactivity, follow these rules:

Example pattern for effect-driven signal updates:

import { DestroyRef, effect, inject, signal, untracked, type Injector } from '@angular/core';

export function injectSomething(optionsFn = () => ({}), injector?: Injector) {
  // resolve dependencies from injector / injection context here
  return ((): any => {
    const destroyRef = inject(DestroyRef);
    const value = signal(0);

    effect(
      () => {
        const opts = untracked(() => optionsFn());
        // imperative signal update inside effect
        value.set(opts.someValue);
      },
      { allowSignalWrites: true }
    );

    return value;
  })();
}

Applying this set of practices will make utilities safer to use across injection contexts, reduce lifecycle leaks, and align with Angular’s current HTTP interceptor direction.