Skip to content

Commit

Permalink
Merge branch 'main' into mst/frozen-field-collection
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelstaib authored Feb 12, 2024
2 parents aaa3bf9 + 9d44f09 commit 74dc3c4
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,23 @@
using HotChocolate.Types.Descriptors;
using HotChocolate.Types.Descriptors.Definitions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using static HotChocolate.Types.EntityFrameworkObjectFieldDescriptorExtensions;
using static HotChocolate.WellKnownMiddleware;

namespace HotChocolate.Data;

internal sealed class DbContextParameterExpressionBuilder<TDbContext>
internal sealed class DbContextParameterExpressionBuilder<TDbContext>(DbContextKind kind)
: IParameterExpressionBuilder
, IParameterFieldConfiguration
where TDbContext : DbContext
{
private readonly ServiceKind _kind;

public DbContextParameterExpressionBuilder(DbContextKind kind)
private readonly ServiceKind _kind = kind switch
{
_kind = kind switch
{
DbContextKind.Pooled => ServiceKind.Pooled,
DbContextKind.Resolver => ServiceKind.Resolver,
_ => ServiceKind.Synchronized,
};
}
DbContextKind.Pooled => ServiceKind.Pooled,
DbContextKind.Resolver => ServiceKind.Resolver,
_ => ServiceKind.Synchronized,
};

public ArgumentKind Kind => ArgumentKind.Service;

Expand Down Expand Up @@ -67,4 +63,4 @@ public void ApplyConfiguration(ParameterInfo parameter, ObjectFieldDescriptor de

public Expression Build(ParameterExpressionBuilderContext context)
=> ServiceExpressionHelper.Build(context.Parameter, context.ResolverContext, _kind);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,22 @@ public static IRequestExecutorBuilder RegisterDbContext<TDbContext>(
new DbContextParameterExpressionBuilder<TDbContext>(kind));
return builder;
}

/// <summary>
/// Automatically registers all DBContexts as resolver scoped services.
/// </summary>
/// <param name="builder">
/// The <see cref="IRequestExecutorBuilder"/>.
/// </param>
/// <returns>
/// An <see cref="IRequestExecutorBuilder"/> that can be used to configure a schema
/// and its execution.
/// </returns>
public static IRequestExecutorBuilder AutoRegisterDbContext(
this IRequestExecutorBuilder builder)
{
builder.Services.AddSingleton<IParameterExpressionBuilder, InferDbContextParameterExpressionBuilder>();
return builder;
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using HotChocolate.Internal;
using HotChocolate.Resolvers.Expressions.Parameters;
using HotChocolate.Types;
using HotChocolate.Types.Descriptors;
using HotChocolate.Types.Descriptors.Definitions;
using Microsoft.EntityFrameworkCore;

namespace HotChocolate.Data;

internal sealed class InferDbContextParameterExpressionBuilder()
: IParameterExpressionBuilder
, IParameterFieldConfiguration
{
public ArgumentKind Kind => ArgumentKind.Service;

public bool IsPure => false;

public bool IsDefaultHandler => false;

public bool CanHandle(ParameterInfo parameter)
=> typeof(DbContext).IsAssignableFrom(parameter.ParameterType);

public void ApplyConfiguration(ParameterInfo parameter, ObjectFieldDescriptor descriptor)
{
ServiceExpressionHelper.ApplyConfiguration(parameter, descriptor, ServiceKind.Resolver);
var definition = descriptor.Extend().Definition;
var placeholderMiddleware = new FieldMiddlewareDefinition(
_ => _ => throw new NotSupportedException(),
key: WellKnownMiddleware.ToList);
var serviceMiddleware =
definition.MiddlewareDefinitions.Last(t => t.Key == WellKnownMiddleware.ResolverService);
var index = definition.MiddlewareDefinitions.IndexOf(serviceMiddleware) + 1;
definition.MiddlewareDefinitions.Insert(index, placeholderMiddleware);
EntityFrameworkObjectFieldDescriptorExtensions.AddCompletionMiddleware(definition, placeholderMiddleware);
}

public Expression Build(ParameterExpressionBuilderContext context)
=> ServiceExpressionHelper.Build(context.Parameter, context.ResolverContext, ServiceKind.Resolver);
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,28 @@ public async Task Resolver_Pipeline_With_Field_DbContext_Is_Created()

result.MatchSnapshot();
}

[Fact]
public async Task Resolver_Pipeline_With_Field_AutoRegistered_DbContext_Is_Created()
{
using AuthorFixture authorFixture = new();

await using var service = new ServiceCollection()
.AddScoped(_ => authorFixture.Context)
.AddGraphQL()
.AddQueryType<Query>()
.AutoRegisterDbContext()
.Services
.BuildServiceProvider();

var result = await service.ExecuteRequestAsync(
QueryRequestBuilder.New()
.SetQuery("{ books { title } }")
.SetServices(service)
.Create());

result.MatchSnapshot();
}

public class Query
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"data": {
"books": [
{
"title": "Foo1"
},
{
"title": "Bar1"
},
{
"title": "Baz1"
}
]
}
}

0 comments on commit 74dc3c4

Please sign in to comment.