Skip to content
This repository was archived by the owner on Feb 7, 2021. It is now read-only.

Commit aae9146

Browse files
authored
feat: implementing forFeature (#64)
Add support for module imports using forFeature method in addition to forRoot. This adds the ability for multiple instances of InMemoryDBService to be registered each with differing configurations. Closes #59
1 parent 0a68aa5 commit aae9146

18 files changed

+283
-48
lines changed

README.md

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ To get started, let's first update our `app.module.ts` to include the necessary
3939

4040
> While we are importing to the AppModule in this example, InMemoryDBModule could be imported in Feature modules just as well.
4141
42+
#### Registering a forRoot InMemoryDBService
43+
4244
```typescript
4345
// app.module.ts
4446

@@ -48,7 +50,7 @@ import { InMemoryDBModule } from '@nestjs-addons/in-memory-db';
4850

4951
@Module({
5052
...
51-
imports: [InMemoryDBModule.forRoot()],
53+
imports: [InMemoryDBModule.forRoot({})],
5254
...
5355
})
5456
export class AppModule {}
@@ -102,6 +104,53 @@ export class UserController {
102104
}
103105
```
104106

107+
## Feature Modules - Registering Multiple Instances using `forFeature`
108+
109+
Registering multiple instances for specific feature modules is super simple. Each feature module is guaranteed isolated to that feature. In order to get up and running you need to do the following:
110+
111+
#### Registering a forFeature InMemoryDBService
112+
113+
For each feature module(s), do the following:
114+
115+
```typescript
116+
// feature-one.module.ts
117+
118+
import { Module } from '@nestjs/common';
119+
import { InMemoryDBModule } from '@nestjs-addons/in-memory-db';
120+
...
121+
122+
@Module({
123+
...
124+
imports: [InMemoryDBModule.forFeature('one', {})],
125+
...
126+
})
127+
export class FeatureOneModule {}
128+
```
129+
130+
As you can see we:
131+
132+
- Imported `InMemoryDBModule` from `@nestjs-addons/in-memory-db`
133+
- Added `InMemoryDBModule` to the `imports` array in the `@Module` of your choice
134+
- Added the `forFeature` method call passing `one` as the feature name
135+
136+
#### Using the Feature Instance
137+
138+
If you would like to use the feature-specific instance, make use of the included `@InjectInMemoryDBService` decorator:
139+
140+
```typescript
141+
@Controller({...})
142+
export class FeatureOneController {
143+
constructor(@InjectInMemoryDBService('one') private oneService: InMemoryDBService<OneEntity>) {}
144+
...
145+
@Get()
146+
getAll(): OneEntity[] {
147+
return this.oneService.getAll();
148+
}
149+
}
150+
```
151+
152+
Using this decorator ensures that the correct instance is injected.
153+
105154
## Docs
106155

107156
[Click here for more detailed API Documentation](API.md)

lib/common/in-memory-db.constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export const IN_MEMORY_DB_SERVICE = 'InMemoryDBService';
2+
export const IN_MEMORY_DB_CONFIG = 'InMemoryDBConfig';

lib/common/in-memory-db.decorators.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { Inject } from '@nestjs/common';
2+
import { getInMemoryDBServiceToken } from './in-memory-db.utils';
3+
4+
export const InjectInMemoryDBService = (featureName: string) =>
5+
Inject(getInMemoryDBServiceToken(featureName));

lib/common/in-memory-db.utils.spec.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { getInMemoryDBServiceToken } from './in-memory-db.utils';
2+
3+
describe('getInMemoryDBServiceToken', () => {
4+
test.each([
5+
['oneInMemoryDBService', 'one'],
6+
['InMemoryDBService', ''],
7+
['InMemoryDBService', null],
8+
['InMemoryDBService', undefined],
9+
])(
10+
'should return %p token given input featureName of %p',
11+
(expectedToken: string, featureName: string) => {
12+
// act
13+
const actualToken = getInMemoryDBServiceToken(featureName);
14+
15+
// assert
16+
expect(actualToken).toEqual(expectedToken);
17+
},
18+
);
19+
});

lib/common/in-memory-db.utils.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { IN_MEMORY_DB_SERVICE } from './in-memory-db.constants';
2+
3+
export function getInMemoryDBServiceToken(featureName?: string) {
4+
return featureName && featureName !== IN_MEMORY_DB_SERVICE
5+
? `${featureName}${IN_MEMORY_DB_SERVICE}`
6+
: IN_MEMORY_DB_SERVICE;
7+
}

lib/common/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './in-memory-db.decorators';
2+
export { getInMemoryDBServiceToken } from './in-memory-db.utils';
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { InMemoryDBConfig, InMemoryDBEntity } from '../interfaces';
2+
import { InMemoryDBService } from '../services';
3+
4+
export function inMemoryDBServiceFactory<T extends InMemoryDBEntity>(
5+
featureConfig: Partial<InMemoryDBConfig> = {},
6+
featureName?: string,
7+
) {
8+
return () =>
9+
new InMemoryDBService<T>({
10+
featureName: featureName
11+
? featureName
12+
: featureConfig.featureName || 'root',
13+
...featureConfig,
14+
});
15+
}

lib/factories/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './in-memory-db-service.factory';

lib/in-memory-db.module.ts

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,33 @@ import { DynamicModule, Module } from '@nestjs/common';
22

33
import { InMemoryDBConfig } from './interfaces';
44
import { InMemoryDBService } from './services';
5-
5+
import {
6+
createInMemoryDBForRootProviders,
7+
createInMemoryDBForFeatureProviders,
8+
} from './providers';
69
@Module({
710
providers: [InMemoryDBService],
811
exports: [InMemoryDBService],
912
})
1013
export class InMemoryDBModule {
1114
public static forRoot(config: Partial<InMemoryDBConfig> = {}): DynamicModule {
15+
const providers = createInMemoryDBForRootProviders(config);
16+
return {
17+
module: InMemoryDBModule,
18+
providers,
19+
exports: providers,
20+
};
21+
}
22+
23+
public static forFeature(
24+
featureName: string,
25+
config: Partial<InMemoryDBConfig> = {},
26+
): DynamicModule {
27+
const providers = createInMemoryDBForFeatureProviders(featureName, config);
1228
return {
1329
module: InMemoryDBModule,
14-
providers: [
15-
{
16-
provide: InMemoryDBService,
17-
useValue: new InMemoryDBService(config),
18-
},
19-
],
20-
exports: [InMemoryDBService],
30+
providers,
31+
exports: providers,
2132
};
2233
}
2334
}

lib/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
import 'reflect-metadata';
2+
import { InjectInMemoryDBService } from './common';
3+
24
export * from './in-memory-db.module';
35
export * from './interfaces';
46
export * from './services';
7+
export { InjectInMemoryDBService };

0 commit comments

Comments
 (0)