Skip to content

Commit

Permalink
Configure mobx & IoC
Browse files Browse the repository at this point in the history
  • Loading branch information
arturdedela committed Mar 9, 2019
1 parent bbf4007 commit 990339b
Show file tree
Hide file tree
Showing 6 changed files with 232 additions and 26 deletions.
135 changes: 135 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 9 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,23 @@
"scripts": {
"start": "webpack-dev-server --mode development --open --hot"
},
"author": "",
"author": "arturdedela",
"license": "ISC",
"dependencies": {
"inversify": "latest",
"inversify-binding-decorators": "latest",
"mobx": "^5.9.0",
"mobx-react": "^5.4.3",
"mobx-react-router": "latest",
"react": "^16.8.3",
"react-dom": "^16.8.3",
"react-router": "^4.3.1",
"reflect-metadata": "^0.1.13",
"semantic-ui-css": "^2.4.1",
"semantic-ui-react": "^0.85.0"
},
"devDependencies": {
"@types/history": "^4.7.2",
"@types/react": "^16.8.6",
"@types/react-dom": "^16.8.2",
"awesome-typescript-loader": "^5.2.1",
Expand Down
32 changes: 9 additions & 23 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,24 @@ import * as React from "react";
import { Segment } from "semantic-ui-react";

import './App.scss';
import {observer} from 'mobx-react';
import {lazyInject} from './IoC';
import {CounterStore} from './CounterStore';

interface IProps {
startCount?: number;
}

interface IState {
counter: number;
}

class App extends React.Component<IProps, IState> {

constructor(props: IProps) {
super(props);

this.state = {
counter: props.startCount
}
}
@observer
class App extends React.Component {
@lazyInject(CounterStore)
counterStore: CounterStore;

render() {
return (
<Segment>
<h1>React webpack</h1>
<p>Counter: {this.state.counter}</p>
<button onClick={() => this.setState({ counter: this.state.counter + 1 })}>Plus</button>
<p>Counter: {this.counterStore.counter}</p>
<button onClick={this.counterStore.increment}>Plus</button>
</Segment>
);
}

static defaultProps: IProps = {
startCount: 0
}
}

export default App;
12 changes: 12 additions & 0 deletions src/CounterStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {observable, action} from "mobx";
import { provide } from './IoC';

@provide.singleton()
export class CounterStore {
@observable counter: number = 0;

@action.bound
increment() {
this.counter++;
}
}
62 changes: 62 additions & 0 deletions src/IoC.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import 'reflect-metadata';
import { Container, ContainerModule, interfaces } from 'inversify';
import { fluentProvide } from 'inversify-binding-decorators';
import { RouterStore } from 'mobx-react-router';

const container = new Container({
autoBindInjectable: true,
defaultScope: 'Singleton',
});

// You can add here external services to container
container.bind(RouterStore).toConstantValue(new RouterStore());

const provide = {
singleton: () => (target: any) =>
fluentProvide(target)
.inSingletonScope()
.done()(target),

transient: () => (target: any) =>
fluentProvide(target)
.inTransientScope()
.done()(target),
};

interface IProvideSyntax {
constraint: (bind: interfaces.Bind, target: any) => any;
implementationType: any;
}

const PROVIDE_METADATA_KEY = 'inversify-binding-decorators:provide';

const lazyInject = (identifier: any) => (target: any, key: string) => {
debugger;
const isBound = container.isBound(identifier);
if (!isBound) {
const provideMetadata = (
Reflect.getMetadata(PROVIDE_METADATA_KEY, Reflect) || []
).filter(
(metadata: IProvideSyntax) => metadata.implementationType === identifier
);

if (provideMetadata.length === 0) {
throw new Error(`Provided identifier isn't registered: ${identifier}`);
}

container.load(
new ContainerModule((bind: any) => {
provideMetadata.forEach((metadata: IProvideSyntax) =>
metadata.constraint(bind, metadata.implementationType)
);
})
);
}

Object.defineProperty(target, key, {
get: () => container.get(identifier),
enumerable: true,
});
};

export { container, provide, lazyInject };
7 changes: 5 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@
"compilerOptions": {
"outDir": "./dist/",
"sourceMap": true,
"noImplicitAny": true,
"lib": ["es6", "dom"],
"module": "commonjs",
"target": "es5",
"jsx": "react"
"jsx": "react",
"noImplicitAny": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true
},
"include": [
"./src/**/*"
Expand Down

0 comments on commit 990339b

Please sign in to comment.