4
4
5
5
## Overview
6
6
7
- GraphQL.DI enhances GraphQL.NET's code-first approach by providing dependency injection support for field resolvers through the ` DIObjectGraphBase ` class. This enables a more maintainable and testable approach to building GraphQL APIs by allowing services to be injected directly into your field resolver classes.
8
-
9
- ## Type-First vs Code-First in GraphQL.NET
7
+ GraphQL.DI enhances GraphQL.NET's code-first approach by providing dependency injection support for
8
+ field resolvers through the ` DIObjectGraphBase ` class. This enables a more maintainable and testable
9
+ approach to building GraphQL APIs by allowing services to be injected directly into your field resolver classes.
10
+
11
+ ## Getting Started
12
+
13
+ 1 . ** Install the NuGet package**
14
+ ``` bash
15
+ dotnet add package Shane32.GraphQL.DI
16
+ ```
17
+ 2 . ** Add ` .AddDI() ` to your ` AddGraphQL(...) ` registration**
18
+ Register your schema and resolvers, for example:
19
+ ``` csharp
20
+ services .AddGraphQL (b => b
21
+ .AddSystemTextJson ()
22
+ .AddSchema <TodoSchema >()
23
+ .AddDI ()
24
+ .AddGraphTypes ()
25
+ .AddClrTypeMappings ()
26
+ .AddExecutionStrategy <SerialExecutionStrategy >(OperationType .Query )
27
+ );
28
+ ```
29
+ 4 . ** Create your DI-based graph types**
30
+ ``` csharp
31
+ public class TodoMutation : DIObjectGraphBase
32
+ {
33
+ private readonly IRepository <Todo > _repository ;
34
+
35
+ public TodoMutation (IRepository <Todo > repository )
36
+ {
37
+ _repository = repository ;
38
+ }
39
+
40
+ public async Task <Todo > AddAsync (string title , string ? notes )
41
+ {
42
+ var todo = new Todo {
43
+ Title = title ,
44
+ Notes = notes ,
45
+ };
46
+ return await _repository .InsertAsync (todo , RequestAborted );
47
+ }
48
+ }
49
+ ```
50
+ 5 . ** Add the new graph types to your schema**
51
+ ``` csharp
52
+ public class MutationType : ObjectGraphType
53
+ {
54
+ public MutationType ()
55
+ {
56
+ Field <NonNullGraphType <TodoMutation >>(" todo" )
57
+ .Resolve (_ => " " );
58
+ }
59
+ }
60
+ ```
61
+
62
+ See the [ Setup] ( #setup ) section below for more detailed instructions on configuring GraphQL.DI in
63
+ your project, including how to configure root types for use with GraphQL.DI.
64
+
65
+ ## Background: Type-First vs Code-First in GraphQL.NET
10
66
11
67
### Type-First Approach
12
68
@@ -58,7 +114,7 @@ public class TodoType : ObjectGraphType<Todo>
58
114
```
59
115
60
116
This can solve both issues noted above -- the data model is separate from the GraphQL type definition,
61
- and services can be resolved via dependency injection in the constructor. However, graph types are
117
+ and services can be resolved via dependency injection in the constructor. However, graph types are
62
118
effectively singletons (typically) within the dependency injection container, so if your services
63
119
(such as ` IRepository ` above) is a scoped service, then your code will not run properly.
64
120
@@ -76,8 +132,8 @@ public class TodoType : ObjectGraphType<Todo>
76
132
.Resolve (context =>
77
133
{
78
134
var repository = context .RequestServices ! .GetRequiredService <IRepository >();
79
- return repository .GetPersonById (context .Source .CompletedByPersonId )) ;
80
- }
135
+ return repository .GetPersonById (context .Source .CompletedByPersonId );
136
+ });
81
137
}
82
138
}
83
139
```
@@ -240,14 +296,14 @@ public static User GetUser(int id) => this.GetById<User>(id);
240
296
public static User GetById <T >(this IResolveFieldContext context , int id )
241
297
{
242
298
var repository = context .RequestServices ! .GetRequiredService <IRepository <T >>();
243
- return repository .GetById (int );
299
+ return repository .GetById (id );
244
300
}
245
301
```
246
302
247
303
## Advanced Usage
248
304
249
305
Please note that unlike GraphQL.NET type-first resolvers, only public methods are resolved by default.
250
- Properties and field are ignored , as well as private or protected members .
306
+ Properties and fields are ignored, as well as private or protected members.
251
307
This more closely mimics the design of controllers within ASP.NET.
252
308
253
309
### Service Lifetime
@@ -360,41 +416,41 @@ All other type-first attributes from GraphQL.NET are supported, such as `[Id]`,
360
416
361
417
## Setup
362
418
363
- 1 . Install the NuGet package :
364
-
365
- ```bash
366
- dotnet add package Shane32 .GraphQL .DI
367
- ```
368
-
369
- 2 . Register your types with the DI container :
370
-
371
- ```csharp
372
- services .AddGraphQL (b => b
373
- .AddSystemTextJson ()
374
- .AddSchema <TodoSchema >()
375
- .AddDI () // Register and configure GraphQL.DI types defined within the assembly
376
- .AddGraphTypes () // Register GraphQL.NET types defined within the assembly
377
- .AddClrTypeMappings () // Enable automatic CLR type mappings
378
- .AddExecutionStrategy <SerialExecutionStrategy >(OperationType .Query ) // Specify serial execution strategy
379
- );
380
- ```
381
-
382
- 3 . Define your schema with root DI graph types (if / as needed ):
383
-
384
- ```csharp
385
- public class TodoSchema : Schema
386
- {
387
- public TodoSchema (
388
- IServiceProvider serviceProvider ,
389
- QueryType queryType , // sample where QueryType inherits DIObjectGraphType<Query>
390
- DIObjectGraphType < Mutation > mutationType ) // sample where Mutation inherits DIObjectGraphBase
391
- : base (serviceProvider )
392
- {
393
- Query = queryType ;
394
- Mutation = mutationType ;
395
- }
396
- }
397
- ```
419
+ 1 . ** Install the NuGet package:**
420
+
421
+ ``` bash
422
+ dotnet add package Shane32.GraphQL.DI
423
+ ```
424
+
425
+ 2 . ** Register your types with the DI container:**
426
+
427
+ ``` csharp
428
+ services .AddGraphQL (b => b
429
+ .AddSystemTextJson ()
430
+ .AddSchema <TodoSchema >()
431
+ .AddDI () // Register and configure GraphQL.DI types defined within the assembly
432
+ .AddGraphTypes () // Register GraphQL.NET types defined within the assembly
433
+ .AddClrTypeMappings () // Enable automatic CLR type mappings
434
+ .AddExecutionStrategy <SerialExecutionStrategy >(OperationType .Query ) // Specify serial execution strategy
435
+ );
436
+ ```
437
+
438
+ 3 . ** Define your schema with root DI graph types (if/as needed):**
439
+
440
+ ``` csharp
441
+ public class TodoSchema : Schema
442
+ {
443
+ public TodoSchema (
444
+ IServiceProvider serviceProvider ,
445
+ QueryType queryType , // sample where QueryType inherits DIObjectGraphType<Query>
446
+ DIObjectGraphType <Mutation > mutationType ) // sample where Mutation inherits DIObjectGraphBase
447
+ : base (serviceProvider )
448
+ {
449
+ Query = queryType ;
450
+ Mutation = mutationType ;
451
+ }
452
+ }
453
+ ```
398
454
399
455
## Additional Samples
400
456
0 commit comments