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

Question: IOC container in a react project #60

Open
fekete965 opened this issue May 3, 2023 · 4 comments
Open

Question: IOC container in a react project #60

fekete965 opened this issue May 3, 2023 · 4 comments

Comments

@fekete965
Copy link

fekete965 commented May 3, 2023

I am fairly new to dependency injection and IOC containers.
I find typed-inject's API much friendlier than similar libraries.
I am trying to make my react project work with typescript and an IOC container using typed-inject.
Has anybody ever done something similar? I would be interested to see any kind of examples. 🙏

@cederron
Copy link

If you follow the tutorial in the readme, then you just inject the service in the component state:

const [service] = React.useState(appInjector.injectClass(MyService));

@fekete965
Copy link
Author

fekete965 commented May 31, 2023

@cederron I have read through the documentation but thanks for the tip.

I thought about making a HOC which would inject the correct services I need but declaring the type definition is a nightmare and I am not super good with that.

I actually did a custom hook which pulls out the correct service from my IOC Container:

const InjectorContainerContext = createContext<Injector<ContainerContext> | null>(null)

interface Props {
  container: Injector<ContainerContext>
}

export const InjectionProvider = ({ children, container }: PropsWithChildren<Props>) => {
  return <InjectorContainerContext.Provider value={container}>{children}</InjectorContainerContext.Provider>
}

export function useInjection<Token extends keyof ContainerContext>(identifier: Token) {
  const container = useContext(InjectorContainerContext)

  if (!container) {
    throw new Error('useInjection must be used within InjectionProvider')
  }

  return useMemo(() => container.resolve(identifier), [container, identifier])
}

Then it can be used like so:

const presenter = useInjection('appPresenter')

(presenter has the correct type in the component)

I was just curious what solution other people come up with :)

@cederron
Copy link

I dont know your requirements and why you need to inject through a context, but if you do as i posted it just works, and types are correct

@fekete965
Copy link
Author

I am not sure if I happen to swap any of the services it will update the useState's value correctly as it would only run once the component's been mounted 🤔

I guess I will need to experiment with it. Thanks a lot for your input! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants