Skip to content

Commit

Permalink
support to configure constants from files
Browse files Browse the repository at this point in the history
  • Loading branch information
Thiago Bustamante committed Mar 8, 2020
1 parent cf12c3c commit 3c9d9c1
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 18 deletions.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,10 @@ For example, you can create the ```ioc.config.ts``` file:
```typescript
import { MyType, MyTypeImpl, MyType2, MyType2Factory } from './my-types';
import { Scope } from 'typescript-ioc';
import * as yaml from 'js-yaml';
import * as fs from 'fs';

const config = yaml.safeLoad(fs.readFileSync(configFileName, 'utf8'));

export default [
{ bind: MyType, to: MyTypeImpl },
Expand All @@ -440,7 +444,8 @@ export default [
factory: MyType2Factory,
withParams: [Date],
scope: Scope.Singleton
}
},
{ bindName: 'config', to: config }
];

```
Expand Down
15 changes: 15 additions & 0 deletions src/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,21 @@ export interface ContainerConfiguration {
withParams?: Array<any>;
}

/**
* A Container constant configuration
*/
export interface ConstantConfiguration {
/**
* The constant name used to refer the constant in the container
*/
bindName: string;
/**
* The constant value
*/
to?: any;
}


/**
* A Configuration Snapshot. Store the state for a specified binding.
* Can then be restored later. Useful for testing.
Expand Down
49 changes: 34 additions & 15 deletions src/typescript-ioc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/

import 'reflect-metadata';
import { Config, ValueConfig, ObjectFactory, Scope, ContainerConfiguration, Snapshot, BuildContext } from './model';
import { Config, ValueConfig, ObjectFactory, Scope, ContainerConfiguration, ConstantConfiguration, Snapshot, BuildContext } from './model';
import { IoCContainer } from './container/container';
import { LocalScope, SingletonScope, RequestScope } from './scopes';

Expand All @@ -15,6 +15,7 @@ export { ObjectFactory };
export { BuildContext };
export { Scope };
export { ContainerConfiguration };
export { ConstantConfiguration };
export { Inject, Factory, Singleton, Scoped, OnlyInstantiableByContainer, InRequestScope } from './decorators';
export { Snapshot };

Expand Down Expand Up @@ -93,24 +94,42 @@ export class Container {
* Import an array of configurations to the Container
* @param configurations
*/
public static configure(...configurations: Array<ContainerConfiguration>) {
public static configure(...configurations: Array<ContainerConfiguration | ConstantConfiguration>) {
configurations.forEach(config => {
const bind = IoCContainer.bind(config.bind);
if (bind) {
if (config.to) {
bind.to(config.to);
} else if (config.factory) {
bind.factory(config.factory);
}
if (config.scope) {
bind.scope(config.scope);
}
if (config.withParams) {
bind.withParams(config.withParams);
}
if ((config as ContainerConfiguration).bind) {
Container.configureType(config as ContainerConfiguration);
} else if ((config as ConstantConfiguration).bindName) {
Container.configureConstant(config as ConstantConfiguration);
}
});
}

private static configureConstant(config: ConstantConfiguration) {
const bind = IoCContainer.bindName(config.bindName);
if (bind) {
if (config.to) {
bind.to(config.to);
}
}
}

private static configureType(config: ContainerConfiguration) {
const bind = IoCContainer.bind(config.bind);
if (bind) {
if (config.to) {
bind.to(config.to);
}
else if (config.factory) {
bind.factory(config.factory);
}
if (config.scope) {
bind.scope(config.scope);
}
if (config.withParams) {
bind.withParams(config.withParams);
}
}
}
}

class ContainerBuildContext extends BuildContext {
Expand Down
20 changes: 18 additions & 2 deletions test/unit/typescript-ioc.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@

import { IoCContainer } from '../../src/container/container';
import { Container, Scope, Config, ObjectFactory } from '../../src/typescript-ioc';
import { BuildContext } from '../../src/model';
import { BuildContext, ValueConfig } from '../../src/model';

jest.mock('../../src/container/container');
const mockBind = IoCContainer.bind as jest.Mock;
const mockBindName = IoCContainer.bindName as jest.Mock;
const mockGet = IoCContainer.get as jest.Mock;
const mockGetType = IoCContainer.getType as jest.Mock;
const mockSnapshot = IoCContainer.snapshot as jest.Mock;
Expand All @@ -14,6 +15,7 @@ const mockFactory = jest.fn();
const mockScope = jest.fn();
const mockWithParams = jest.fn();
let bindResult: Config;
let bindNameResult: ValueConfig;

describe('Container', () => {

Expand All @@ -24,7 +26,10 @@ describe('Container', () => {
scope: mockScope,
withParams: mockWithParams
};
mockBind.mockReturnValue(bindResult);
bindNameResult = {
to: mockTo
};

});

beforeEach(() => {
Expand All @@ -35,6 +40,10 @@ describe('Container', () => {
mockFactory.mockClear();
mockScope.mockClear();
mockWithParams.mockClear();
mockBind.mockClear();
mockBindName.mockClear();
mockBind.mockReturnValue(bindResult);
mockBindName.mockReturnValue(bindNameResult);
});

class MyBaseType { }
Expand Down Expand Up @@ -106,5 +115,12 @@ describe('Container', () => {

expect(mockWithParams).toBeCalledWith(['param']);
});

it('should configure constants in the IoC Container', () => {
Container.configure({ bindName: 'myProp', to: 'a value' });

expect(mockBindName).toBeCalledWith('myProp');
expect(mockTo).toBeCalledWith('a value');
});
});
});

0 comments on commit 3c9d9c1

Please sign in to comment.