Dependency Injection
Tanka GraphQL servers is built on top of the ASP.NET Core and uses the builtin dependency injection services.
The recommended lifetime of a schema in Tanka is singleton as long as the schema does not change. This adds a challenge when using services which require scoped lifetime. Usually the scope is defined as HTTP request.
Lets define a dependency
public class Service
{
public async Task<string> CallService()
{
await Task.Delay(100);
return "Test";
}
}
- Use
ResolverContext
: context has an property called `RequestServices.
[Fact]
public async Task Part5_ServiceProvider_RequestServices()
{
// Create builder and load sdl
var builder = new SchemaBuilder()
.Add(@"
type Query {
name: String
}
");
// Build schema with the resolver
var schema = await builder.Build(new SchemaBuildOptions
{
Resolvers = new ResolversMap
{
{
"Query", "name", async (ResolverContext context) =>
{
context.ResolvedValue = await context.RequestServices.GetRequiredService<Service>().CallService();
}
}
}
});
// we create an executor with ServiceProvider
var result = await new Executor(new ExecutorOptions()
{
Schema = schema,
ServiceProvider = new ServiceCollection()
.AddDefaultTankaGraphQLServices()
.AddSingleton<Service>()
.BuildServiceProvider()
}).Execute(new GraphQLRequest("{name}"));
result.ShouldMatchJson("""
{
"data": {
"name": "Test"
}
}
""");
}
- Use a parameter on delegate, if the property with the name does not exists on
ResolverContext
it will be resolved fromRequestServices
[Fact]
public async Task Part5_ServiceProvider_Delegate_with_parameters()
{
// Create builder and load sdl
var builder = new SchemaBuilder()
.Add(@"
type Query {
name: String
}
");
// Build schema with the resolver
var schema = await builder.Build(new SchemaBuildOptions
{
Resolvers = new ResolversMap
{
{
"Query", "name", async (Service service) => await service.CallService()
}
}
});
// we create an executor with ServiceProvider
var result = await new Executor(new ExecutorOptions()
{
Schema = schema,
ServiceProvider = new ServiceCollection()
.AddDefaultTankaGraphQLServices()
.AddSingleton<Service>()
.BuildServiceProvider()
}).Execute(new GraphQLRequest("{name}"));
result.ShouldMatchJson("""
{
"data": {
"name": "Test"
}
}
""");
}