InversifyJS
InversifyJS copied to clipboard
Nested @lazyInject not working
I am writing a react app and I have a nested @lazyInject that is not working.
I am trying to use inversify to inject my components as well as other classes used by the components itself.
Here is an example of the problem I am having:
I have a header injected with @lazyInject in my App component.
export class App extends React.Component<{}, {}> implements IApp {
@lazyInject(TYPES.Header)
public header: React.ComponentClass<{}>;
public render() {
return (
<div className="App">
<this.header />
<p className="App-intro">
To get started, edit <code>src/App.tsx</code> and save to reload.
</p>
</div>
);
}
}
then on the header component I have another lazyInject for the headerInfo object
export class Header extends React.Component<{}, {}> implements IHeader {
@lazyInject(TYPES.HeaderInfo)
public headerInfo: IHeaderInfo
public render() {
return (
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcome to React</h1>
</header>
);
}
}
This is not working, but if I remove either one them and have just one lazyInject then it works fine.
Here is my inversify.config
import 'reflect-metadata';
import { Container } from 'inversify';
import getDecorators from 'inversify-inject-decorators';
import TYPES from './types';
import { App, IApp } from './components/App';
import { IHeader } from './components/IHeader';
import { IHeaderInfo, HeaderInfo } from './components/IHeaderInfo';
import { Header } from './components/Header';
const container = new Container();
const {lazyInject} = getDecorators(container);
const headerInfo = new HeaderInfo();
headerInfo.name = 'test';
container.bind<IApp>(TYPES.App).toConstructor<IApp>(App);
container.bind<IHeader>(TYPES.Header).toConstructor<IHeader>(Header);
container.bind<IHeaderInfo>(TYPES.HeaderInfo).toConstantValue(headerInfo);
export {
lazyInject,
container
};
Here is the error
TypeError: Object(...) is not a function
(anonymous function)
D:/Projects/PD/react/inversifyHello/src/components/Header.tsx:12
9 |
10 |
11 | export class Header extends React.Component<{}, {}> implements IHeader {
> 12 | @lazyInject(TYPES.HeaderInfo)
13 | public headerInfo: IHeaderInfo
14 |
15 | public render() {
View compiled
./src/components/Header.tsx
D:/Projects/PD/react/inversifyHello/src/components/Header.tsx:23
20 | </header>
21 | );
22 | }
> 23 | }
24 |
25 | export default Header;
26 |
View compiled
▶ 2 stack frames were collapsed.
./src/inversify.config.ts
D:/Projects/PD/react/inversifyHello/src/inversify.config.ts:1
> 1 | import 'reflect-metadata';
2 | import { Container } from 'inversify';
3 | import getDecorators from 'inversify-inject-decorators';
4 |
View compiled
▶ 5 stack frames were collapsed.
./src/index.tsx
D:/Projects/PD/react/inversifyHello/src/index.tsx:1
> 1 | import * as React from 'react';
2 | import * as ReactDOM from 'react-dom';
3 | import App from './components/App';
4 | import './index.css';
Hi @inaiei,
Did you find any solution for this problem?
I have the same problem in vue.js Did you find any solution for this problem?
I had a similar problem... just in case it helps someone.
In my case I had exported the container and decorator from a ioc.ts
file which was itself exported via an index.ts
file.
That worked for basic DI, but didn't work for the lazyInject
decorator as soon as used in two "circular" classes. the import of all exports of the ioc stuff resulted in undefined
.
As soon as I changed to directly import from the ioc.ts
instead of the index.ts
it started working. So instead of use this two files, I just put everything from ioc.ts
directly in the corresponding index.ts
and it still worked.
did not work, as soon consumed by more than one file that depend on each other.
src
ioc
ioc.ts <-exports the container and decorators (but never consumed directly by any other file)
index.ts <-export * from ioc.ts
class1.ts <- import via src/ioc
class2.ts <- import via src/ioc
when class1.ts
and class2.ts
depends on each other, the following import paths do not work:
class1.ts -> src/ioc/index.ts -> src/ioc/ioc.ts
class2.ts -> src/ioc/index.ts -> src/ioc/ioc.ts
works:
src
ioc
index.ts <-exports the container and decorators
class1.ts <- import via src/ioc/ioc.ts
class2.ts <- import via src/ioc/ioc.ts
when class1.ts
and class2.ts
depends on each other, the following import paths do work:
class1.ts -> src/ioc/index.ts
class2.ts -> src/ioc/index.ts
PS: the strange thing is... I used breakpoints to check if class1.ts
or class2.ts
was called before ioc.ts
but this was not the case... so something behaves badly with the module resolution.
I realize this is an old issue, but I ran into this problem recently and found a workaround.
The problem exists because of a circular dependency between a class (in the case above, the Header
class) and the inversify.config'.
inversify.configneeds to import
Headerin order to create the bindings but
Headerneeds access to
lazyInjectwhich is created in
inversify.config`.
The solution is to split your existing inversify.config
into three files.
- Does nothing except create the container (in my case it is called
container.ts
) - Imports the container from the previous file and adds the bindings (in my case named
inversify.config.ts
) - Imports file 1 (not 2!), calls
getDecorators()
and exportslazyInject
Your class would then import lazyInject
from that third file instead of inversify.config
.
I have the same problem in react.