Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: not working function dependency injection examples from docs #813

Open
sergiycheck opened this issue Jul 13, 2022 · 3 comments
Open
Labels
status: needs triage Issues which needs to be reproduced to be verified report. type: fix Issues describing a broken feature.

Comments

@sergiycheck
Copy link

Description

I'm reading docs here github docs and I find that function dependency
injection examples does not work and Service decorator does not accept function arg.

Minimal code-snippet showcasing the problem

export const PostRepository = Service(() => ({
  getName() {
    return 'hello from post repository';
  },
}));

Expected behavior

Actual behavior

image

typedi version

{
 "typedi": "^0.10.0"
}
@sergiycheck sergiycheck added status: needs triage Issues which needs to be reproduced to be verified report. type: fix Issues describing a broken feature. labels Jul 13, 2022
@maxbol
Copy link

maxbol commented Dec 29, 2022

+1 on this, any fix in sight?

@attilaorosz
Copy link
Member

I might be missing something here but the docs says you have to provide your factory function in the factory property.

@maxbol
Copy link

maxbol commented Jan 3, 2023

Seems like this feature was removed in favor of Container.set({ factory }):

9228bfa

If anyone is interested, I was quite easily able to recreate it. Using mapped tuple types from ts 3.1 I was also able to simplify the types quite a bit:

import Container, { ContainerInstance, ServiceIdentifier, Token } from "typedi";

export type WithDependenciesFactoryArgs<Deps extends ServiceIdentifier<any>[]> =
  {
    [K in keyof Deps]: WithDependenciesResolvedDep<Deps[K]>;
  };

export type WithDependenciesFactory<
  ServiceDependencies extends ServiceIdentifier<any>[],
  ServiceType,
> = (...args: WithDependenciesFactoryArgs<ServiceDependencies>) => ServiceType;

export type WithDependenciesResolvedDep<Identifier> =
  Identifier extends ServiceIdentifier<infer T> ? T : never;

export function withDependenciesFactory<
  ServiceDependencies extends ServiceIdentifier<any>[],
  ServiceType,
>(
  factory: WithDependenciesFactory<ServiceDependencies, ServiceType>,
  ...dependencies: ServiceDependencies
) {
  const serviceId = new Token<ServiceType>();

  Container.set({
    eager: false,
    factory: [
      class DefaultFactory {
        create(container: ContainerInstance) {
          const params = dependencies.map((dependency) => {
            return container.get(dependency);
          }) as WithDependenciesFactoryArgs<ServiceDependencies>;
          return factory(...params);
        }
      },
      "create",
    ],
    global: false,
    id: serviceId,
    multiple: false,
    transient: false,
  });

  return serviceId;
}

To use:

const MyService = withDependenciesFactory(
   (depA, depB, depC) => {
      return {
         sum: () => depA.count() + depB.count() + depC.count()
      }
   },
   DependencyA,
   DependencyB,
   DependencyC
);

const myService = Container.get(MyService);

myService.sum();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: needs triage Issues which needs to be reproduced to be verified report. type: fix Issues describing a broken feature.
Development

No branches or pull requests

3 participants