Skip to content

Commit bce009a

Browse files
author
hirsch88
committed
Add di to graphql
1 parent 018cf87 commit bce009a

File tree

10 files changed

+113
-13
lines changed

10 files changed

+113
-13
lines changed

src/api/mutations/CreatePetMutation.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { PetType } from '../types/PetType';
1010
import { PetService } from '../services/PetService';
1111
import { GraphQLContext, Mutation } from '../../lib/graphql';
1212
import { Pet } from '../models/Pet';
13+
import { Logger, LoggerInterface } from '../../decorators/Logger';
14+
1315

1416
interface CreatePetMutationArguments {
1517
name: string;
@@ -24,9 +26,16 @@ export class CreatePetMutation extends AbstractGraphQLMutation<GraphQLContext<an
2426
age: { type: new GraphQLNonNull(GraphQLInt) },
2527
};
2628

29+
constructor(
30+
private petService: PetService,
31+
@Logger(__filename) private log: LoggerInterface
32+
) {
33+
super();
34+
}
35+
2736
public async run(root: any, args: CreatePetMutationArguments, context: GraphQLContext<any, any>): Promise<Pet> {
28-
const petService = context.container.get<PetService>(PetService);
29-
const pet = await petService.create(plainToClass(Pet, args));
37+
const pet = await this.petService.create(plainToClass(Pet, args));
38+
this.log.info('Successfully created a new pet');
3039
return pet;
3140
}
3241
}

src/api/queries/GetPetsQuery.ts

+9-3
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,25 @@ import { GraphQLFieldConfig, GraphQLList } from 'graphql';
22
import { Query, AbstractGraphQLQuery, GraphQLContext } from './../../lib/graphql';
33
import { PetService } from '../services/PetService';
44
import { PetType } from './../types/PetType';
5-
import { Logger } from '../../core/Logger';
65
import { Pet } from '../models/Pet';
6+
import { Logger, LoggerInterface } from '../../decorators/Logger';
7+
78

89
@Query()
910
export class GetPetsQuery extends AbstractGraphQLQuery<GraphQLContext<any, any>, Pet[], any> implements GraphQLFieldConfig {
1011
public type = new GraphQLList(PetType);
1112
public allow = [];
1213
public args = {};
1314

14-
private log = new Logger(__filename);
15+
constructor(
16+
private petService: PetService,
17+
@Logger(__filename) private log: LoggerInterface
18+
) {
19+
super();
20+
}
1521

1622
public async run(root: any, args: any, context: GraphQLContext<any, any>): Promise<Pet[]> {
17-
const pets = await context.container.get<PetService>(PetService).find();
23+
const pets = await this.petService.find();
1824
this.log.info(`Found ${pets.length} pets`);
1925
return pets;
2026
}

src/api/queries/GetUsersQuery.ts

+9-3
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,24 @@ import { Query, AbstractGraphQLQuery, GraphQLContext } from './../../lib/graphql
33
import { UserService } from '../services/UserService';
44
import { UserType } from './../types/UserType';
55
import { User } from '../models/User';
6-
import { Logger } from '../../core/Logger';
6+
import { Logger, LoggerInterface } from '../../decorators/Logger';
7+
78

89
@Query()
910
export class GetUsersQuery extends AbstractGraphQLQuery<GraphQLContext<any, any>, User[], any> implements GraphQLFieldConfig {
1011
public type = new GraphQLList(UserType);
1112
public allow = [];
1213
public args = {};
1314

14-
private log = new Logger(__filename);
15+
constructor(
16+
private userService: UserService,
17+
@Logger(__filename) private log: LoggerInterface
18+
) {
19+
super();
20+
}
1521

1622
public async run(root: any, args: any, context: GraphQLContext<any, any>): Promise<User[]> {
17-
const users = await context.container.get<UserService>(UserService).find();
23+
const users = await this.userService.find();
1824
this.log.info(`Found ${users.length} users`);
1925
return users;
2026
}

src/lib/graphql/Mutation.ts

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { getMetadataArgsStorage } from './index';
44
export function Mutation(): any {
55
return (object: () => void) => {
66
getMetadataArgsStorage().mutations.push({
7+
name: object.name,
78
target: object,
89
});
910
};

src/lib/graphql/MutationMetadataArgs.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export interface MutationMetadataArgs {
2+
name: string;
23
/**
34
* Indicates object which is used by this controller.
45
*/

src/lib/graphql/Query.ts

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { getMetadataArgsStorage } from './index';
44
export function Query(): any {
55
return (object: () => void) => {
66
getMetadataArgsStorage().queries.push({
7+
name: object.name,
78
target: object,
89
});
910
};

src/lib/graphql/QueryMetadataArgs.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export interface QueryMetadataArgs {
2+
name: string;
23
/**
34
* Indicates object which is used by this controller.
45
*/

src/lib/graphql/container.ts

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
2+
/**
3+
* Container options.
4+
*/
5+
export interface UseContainerOptions {
6+
7+
/**
8+
* If set to true, then default container will be used in the case if given container haven't returned anything.
9+
*/
10+
fallback?: boolean;
11+
12+
/**
13+
* If set to true, then default container will be used in the case if given container thrown an exception.
14+
*/
15+
fallbackOnErrors?: boolean;
16+
17+
}
18+
19+
/**
20+
* Container to be used by this library for inversion control. If container was not implicitly set then by default
21+
* container simply creates a new instance of the given class.
22+
*/
23+
const defaultContainer: { get<T>(someClass: { new(...args: any[]): T } | (() => void)): T } = new (class {
24+
private instances: Array<{ type: any, object: any }> = [];
25+
public get<T>(someClass: { new(...args: any[]): T }): T {
26+
let instance = this.instances.find(i => i.type === someClass);
27+
if (!instance) {
28+
instance = { type: someClass, object: new someClass() };
29+
this.instances.push(instance);
30+
}
31+
32+
return instance.object;
33+
}
34+
})();
35+
36+
let userContainer: { get<T>(someClass: { new(...args: any[]): T } | (() => void)): T };
37+
let userContainerOptions: UseContainerOptions;
38+
39+
/**
40+
* Sets container to be used by this library.
41+
*/
42+
export function useContainer(iocContainer: { get(someClass: any): any }, options?: UseContainerOptions): void {
43+
userContainer = iocContainer;
44+
if (options) {
45+
userContainerOptions = options;
46+
}
47+
}
48+
49+
/**
50+
* Gets the IOC container used by this library.
51+
*/
52+
export function getFromContainer<T>(someClass: { new(...args: any[]): T } | (() => void)): T {
53+
if (userContainer) {
54+
try {
55+
const instance = userContainer.get(someClass);
56+
if (instance) {
57+
return instance;
58+
}
59+
60+
if (!userContainerOptions || !userContainerOptions.fallback) {
61+
return instance;
62+
}
63+
64+
} catch (error) {
65+
if (!userContainerOptions || !userContainerOptions.fallbackOnErrors) {
66+
throw error;
67+
}
68+
}
69+
}
70+
return defaultContainer.get<T>(someClass);
71+
}

src/lib/graphql/index.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@ import * as GraphQLHTTP from 'express-graphql';
33
import * as DataLoader from 'dataloader';
44
import { GraphQLSchema, GraphQLObjectType } from 'graphql';
55
import { Container as container, ObjectType } from 'typedi';
6+
import { Repository, getCustomRepository, getRepository } from 'typeorm';
67

78
import { GraphQLContext, GraphQLContextDataLoader } from './GraphQLContext';
89
import { MetadataArgsStorage } from './MetadataArgsStorage';
910
import { importClassesFromDirectories } from './importClassesFromDirectories';
1011
import { handlingErrors, getErrorCode, getErrorMessage } from './graphql-error-handling';
1112
import { ensureInputOrder } from './dataloader';
12-
import { Repository, getCustomRepository, getRepository } from 'typeorm';
13+
import { getFromContainer } from './container';
1314

1415
// -------------------------------------------------------------------------
1516
// Main exports
@@ -22,6 +23,7 @@ export * from './AbstractGraphQLHooks';
2223
export * from './AbstractGraphQLQuery';
2324
export * from './GraphQLContext';
2425
export * from './graphql-error-handling';
26+
export * from './container';
2527

2628
// -------------------------------------------------------------------------
2729
// Main Functions
@@ -168,8 +170,8 @@ export function createSchema(options: GraphQLSchemaOptions): GraphQLSchema {
168170
}
169171

170172
const queries = {};
171-
queryClasses.forEach(queryClass => {
172-
queries[createQueryName(queryClass.name)] = new queryClass();
173+
getMetadataArgsStorage().queries.forEach(queryMetdadata => {
174+
queries[createQueryName(queryMetdadata.name)] = getFromContainer(queryMetdadata.target);
173175
});
174176

175177
const RootQuery = new GraphQLObjectType({
@@ -186,8 +188,8 @@ export function createSchema(options: GraphQLSchemaOptions): GraphQLSchema {
186188
}
187189

188190
const mutations = {};
189-
mutationClasses.forEach(mutationClass => {
190-
mutations[createMutationName(mutationClass.name)] = new mutationClass();
191+
getMetadataArgsStorage().mutations.forEach(mutationMetdadata => {
192+
mutations[createMutationName(mutationMetdadata.name)] = getFromContainer(mutationMetdadata.target);
191193
});
192194

193195
const RootMutation: GraphQLObjectType = new GraphQLObjectType({

src/loaders/iocLoader.ts

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Container } from 'typedi';
22
import { useContainer as ormUseContainer } from 'typeorm';
33
import { useContainer as routingUseContainer } from 'routing-controllers';
4+
import { useContainer as graphqlUseContainer } from '../lib/graphql';
45
import { MicroframeworkSettings, MicroframeworkLoader } from 'microframework-w3tec';
56

67

@@ -11,5 +12,6 @@ export const iocLoader: MicroframeworkLoader = (settings: MicroframeworkSettings
1112
*/
1213
routingUseContainer(Container);
1314
ormUseContainer(Container);
15+
graphqlUseContainer(Container);
1416

1517
};

0 commit comments

Comments
 (0)