Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update sample #18

Merged
merged 1 commit into from
Apr 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions Sample/GraphTypes/TodoType.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using GraphQL.DataLoader;
using GraphQL.DI;
using Sample.DataLoaders;
Expand Down Expand Up @@ -31,12 +28,13 @@ public class TodoObjType : DIObjectGraphBase<Todo>
public static bool Completed(Todo source) => source.Completed;
public static DateTime? CompletedOn(Todo source) => source.CompletionDate;

public IDataLoaderResult<Person> CompletedBy(Todo source)
// here it is using an instance field "Source"
public IDataLoaderResult<Person> CompletedBy()
{
if (!source.CompletedByPersonId.HasValue)
if (!Source.CompletedByPersonId.HasValue)
return null;

return _personDataLoader.LoadAsync(source.CompletedByPersonId.Value);
return _personDataLoader.LoadAsync(Source.CompletedByPersonId.Value);
}
}
}
20 changes: 3 additions & 17 deletions Sample/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
using System.Diagnostics;
using EfLocalDb;
using GraphQL;
using GraphQL.AspNetCore3;
using GraphQL.DI;
using GraphQL.MicrosoftDI;
using GraphQL.Server;
using GraphQL.SystemTextJson;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Sample.DataLoaders;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

namespace Sample
{
Expand All @@ -34,21 +29,12 @@ public void ConfigureServices(IServiceCollection services)
services.AddRazorPages();

services.AddGraphQL(b => b
.AddSchema<TodoSchema>()
.ConfigureExecutionOptions(opts => opts.UnhandledExceptionDelegate = async e => Debug.WriteLine($"Unhandled exception:\n{e.Exception}\n"))
.AddSystemTextJson()
.AddDIGraphTypes()
.AddClrTypeMappings()
.AddGraphTypes());
services.AddSingleton<TodoSchema>();
//foreach (var type in typeof(TodoSchema).Assembly.GetTypes().Where(x => x.IsClass && !x.IsAbstract && !x.IsGenericTypeDefinition)) {
// var baseType = type.BaseType;
// while (baseType != null) {
// if (baseType.IsGenericType && baseType.GetGenericTypeDefinition() == typeof(DIObjectGraphBase<>)) {
// services.AddScoped(type);
// break;
// }
// baseType = baseType.BaseType;
// }
//}

//construct temporary database with scoped dbcontext instances
services.AddSingleton(_ => new SqlInstance<TodoDbContext>(builder => new TodoDbContext(builder.Options)));
Expand Down
73 changes: 0 additions & 73 deletions Sample/TodoSchema.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using GraphQL.DI;
using GraphQL.Types;
using Sample.GraphTypes;

Expand All @@ -13,76 +8,8 @@ public class TodoSchema : Schema
{
public TodoSchema(IServiceProvider serviceProvider, QueryType query, MutationType mutation) : base(serviceProvider)
{
//this code will be an extension in a future version of GraphQL.NET
foreach (var typeMapping in GetClrTypeMappings(typeof(TodoSchema).Assembly)) {
RegisterTypeMapping(typeMapping.ClrType, typeMapping.GraphType);
}

Query = query;
Mutation = mutation;
}


/// <summary>
/// Scans the specified assembly for classes that inherit from <see cref="ObjectGraphType{TSourceType}"/>,
/// <see cref="InputObjectGraphType{TSourceType}"/>, or <see cref="EnumerationGraphType{TEnum}"/>, and
/// returns a list of mappings between matched classes and the source type or underlying enum type.
/// Skips classes where the source type is <see cref="object"/>, or where the class is marked with
/// the <see cref="DoNotMapClrTypeAttribute"/>.
/// </summary>
public static List<(Type ClrType, Type GraphType)> GetClrTypeMappings(Assembly assembly)
{
var typesToRegister = new Type[]
{
typeof(ObjectGraphType<>),
typeof(InputObjectGraphType<>),
typeof(EnumerationGraphType<>),
};

//create a list of type mappings
var typeMappings = new List<(Type clrType, Type graphType)>();

//loop through each type in the specified assembly
foreach (var graphType in assembly.GetTypes()) {
//skip types that are not graph types
if (!typeof(IGraphType).IsAssignableFrom(graphType))
continue;

//skip abstract types and interfaces
if (graphType.IsAbstract || graphType.IsInterface)
continue;

//skip types marked with the DoNotRegister attribute
if (graphType.GetCustomAttributes(false).Any(y => y.GetType() == typeof(DoNotMapClrTypeAttribute)))
continue;

//start with the base type
var baseType = graphType.BaseType;
while (baseType != null) {
//skip types marked with the DoNotRegister attribute
if (baseType.GetCustomAttributes(false).Any(y => y.GetType() == typeof(DoNotMapClrTypeAttribute)))
break;

//look for generic types that match our list above
if (baseType.IsConstructedGenericType && typesToRegister.Contains(baseType.GetGenericTypeDefinition())) {
//get the base type
var clrType = baseType.GetGenericArguments()[0];

//as long as it's not of type 'object', register it
if (clrType != typeof(object))
typeMappings.Add((clrType, graphType));

//skip to the next type
break;
}

//look up the inheritance chain for a match
baseType = baseType.BaseType;
}
}

//return the list of type mappings
return typeMappings;
}
}
}