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

Split Construction of Graph Types into individual modules #121

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
39 changes: 0 additions & 39 deletions src/AspNetCoreMulti/Example/GraphQL.cs

This file was deleted.

44 changes: 44 additions & 0 deletions src/AspNetCoreMulti/Example/GraphQL/Mutations.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System;
using Example.Repositories;
using GraphQL;
using GraphQL.Types;
using Microsoft.Extensions.DependencyInjection;

namespace Example.GraphQL;

public interface IMutationFieldsProvider
{
void AddMutationFields(ObjectGraphType objectGraph);
}

public interface ICatMutation : IMutationFieldsProvider { }

public class CatBreedUpdateMutation : ICatMutation
{
private readonly IServiceProvider _serviceProvider;

public CatBreedUpdateMutation(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}

public void AddMutationFields(ObjectGraphType objectGraph)
{
var args = new QueryArguments
{
new QueryArgument<StringGraphType> { Name = "breedName" },
new QueryArgument<StringGraphType> { Name = "newBreedName" }
};

objectGraph.Field<CatType>("updateCatBreed", arguments: args, resolve: context =>
{
var breed = context.GetArgument<string>("breedName");
var newBreed = context.GetArgument<string>("newBreedName");
using var scope = _serviceProvider.CreateScope();
var catRepository = scope.ServiceProvider.GetRequiredService<CatRepository>();
var result = catRepository.UpdateCatBreedName(breed, newBreed);

return result;
});
}
}
83 changes: 83 additions & 0 deletions src/AspNetCoreMulti/Example/GraphQL/Queries.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using System;
using Example.Repositories;
using GraphQL.Types;
using Microsoft.Extensions.DependencyInjection;

namespace Example.GraphQL;

public interface IQueryFieldsProvider
{
void AddQueryFields(ObjectGraphType objectGraph);
}

public interface IDogQuery : IQueryFieldsProvider { }

public interface ICatQuery : IQueryFieldsProvider { }

public class DogQuery : IDogQuery
{
private readonly IServiceProvider _serviceProvider;

public DogQuery(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}

public void AddQueryFields(ObjectGraphType objectGraph)
{
objectGraph.Field<StringGraphType>("say", resolve: context => "woof woof woof");

objectGraph.Field<NonNullGraphType<ListGraphType<NonNullGraphType<DogType>>>>("dogBreeds", resolve: context =>
{
using var scope = _serviceProvider.CreateScope();
var dogRepository = scope.ServiceProvider.GetRequiredService<DogRepository>();
var dogs = dogRepository.GetDogs();
return dogs;
});
}
}

public class DogImageDetailsQuery : IDogQuery
{
private readonly IServiceProvider _serviceProvider;

public DogImageDetailsQuery(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}

public void AddQueryFields(ObjectGraphType objectGraph)
{
objectGraph.FieldAsync<NonNullGraphType<ImageDetailsType>>("dogImageDetails", resolve: async context =>
{
using var scope = _serviceProvider.CreateScope();
var imageDetailsRepository = scope.ServiceProvider.GetRequiredService<DogImageDetailsRepository>();
var imageDetails = await imageDetailsRepository.GetDogImageDetailsAsync();
return imageDetails;
});
}
}

public class CatQuery : ICatQuery
{
private readonly IServiceProvider _serviceProvider;

public CatQuery(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}

public void AddQueryFields(ObjectGraphType objectGraph)
{
objectGraph.Field<StringGraphType>("say", resolve: context => "meow meow meow");

objectGraph.Field<NonNullGraphType<ListGraphType<NonNullGraphType<CatType>>>>("catBreeds", resolve: context =>
{
using var scope = _serviceProvider.CreateScope();
var catRepository = scope.ServiceProvider.GetRequiredService<CatRepository>();
var cats = catRepository.GetCats();
return cats;
});
}
}

15 changes: 15 additions & 0 deletions src/AspNetCoreMulti/Example/GraphQL/RootMutations.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System.Collections.Generic;
using GraphQL.Types;

namespace Example.GraphQL;

public class CatRootMutation : ObjectGraphType
{
public CatRootMutation(IEnumerable<ICatMutation> mutations)
{
foreach (var mutation in mutations)
{
mutation.AddMutationFields(this);
}
}
}
26 changes: 26 additions & 0 deletions src/AspNetCoreMulti/Example/GraphQL/RootQueries.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.Collections.Generic;
using GraphQL.Types;

namespace Example.GraphQL;

public class DogRootQuery : ObjectGraphType
{
public DogRootQuery(IEnumerable<IDogQuery> dogQueries)
{
foreach (var dogQuery in dogQueries)
{
dogQuery.AddQueryFields(this);
}
}
}

public class CatRootQuery : ObjectGraphType
{
public CatRootQuery(IEnumerable<ICatQuery> catQueries)
{
foreach (var catQuery in catQueries)
{
catQuery.AddQueryFields(this);
}
}
}
23 changes: 23 additions & 0 deletions src/AspNetCoreMulti/Example/GraphQL/Schemas.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using GraphQL.Types;

namespace Example.GraphQL;

public class DogSchema : Schema
{
public DogSchema(IServiceProvider provider, DogRootQuery query)
: base(provider)
{
Query = query;
}
}

public class CatSchema : Schema
{
public CatSchema(IServiceProvider provider, CatRootQuery query, CatRootMutation mutation)
: base(provider)
{
Query = query;
Mutation = mutation;
}
}
27 changes: 27 additions & 0 deletions src/AspNetCoreMulti/Example/GraphQL/Types.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using GraphQL.Types;

namespace Example.GraphQL;

public class DogType : ObjectGraphType<Dog>
{
public DogType()
{
Field(x => x.Breed);
}
}

public class CatType : ObjectGraphType<Cat>
{
public CatType()
{
Field(x => x.Breed);
}
}

public class ImageDetailsType : ObjectGraphType<ImageDetails>
{
public ImageDetailsType()
{
Field(x => x.Url);
}
}
9 changes: 4 additions & 5 deletions src/AspNetCoreMulti/Example/GraphQLUserContext.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
using System.Collections.Generic;
using System.Security.Claims;

namespace Example
namespace Example;

public class GraphQLUserContext : Dictionary<string, object>
{
public class GraphQLUserContext : Dictionary<string, object>
{
public ClaimsPrincipal User { get; set; }
}
public ClaimsPrincipal User { get; set; }
}
21 changes: 21 additions & 0 deletions src/AspNetCoreMulti/Example/Models.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace Example;

public interface IBreed
{
public string Breed { get; set; }
}

public class Dog : IBreed
{
public string Breed { get; set; }
}

public class Cat : IBreed
{
public string Breed { get; set; }
}

public class ImageDetails
{
public string Url { get; set; }
}
28 changes: 28 additions & 0 deletions src/AspNetCoreMulti/Example/Repositories/CatRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.Collections.Generic;
using System.Linq;

namespace Example.Repositories;
public class CatRepository
{
private static readonly List<Cat> _cats = new()
{
new Cat { Breed = "Abyssinian" },
new Cat { Breed = "American Bobtail" },
new Cat { Breed = "Burmese" }
};

public IEnumerable<Cat> GetCats() => _cats.AsEnumerable();

public Cat UpdateCatBreedName(string oldName, string newName)
{
var match = _cats.FirstOrDefault(x => x.Breed == oldName);
if (match == null)
{
throw new System.Exception("Cannot find that cat !");
}

match.Breed = newName;

return match;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System;
using System.Net.Http;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;

namespace Example.Repositories;
public class DogImageDetailsRepository
{
private readonly IHttpClientFactory _httpClientFactory;

public DogImageDetailsRepository(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}

public async Task<ImageDetails> GetDogImageDetailsAsync()
{
try
{
var client = _httpClientFactory.CreateClient("DogsApi");
var result = await client.GetStringAsync("api/breeds/image/random");
var apiResponse = JsonSerializer.Deserialize<DogsImageApiResponse>(result);

return new ImageDetails { Url = apiResponse.Message };
}
catch (Exception ex)
{
return new ImageDetails { Url = ex.Message };
}
}

private class DogsImageApiResponse
{
[JsonPropertyName("status")]
public string Status { get; set; }

[JsonPropertyName("message")]
public string Message { get; set; }
}
}
15 changes: 15 additions & 0 deletions src/AspNetCoreMulti/Example/Repositories/DogRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System.Collections.Generic;
using System.Linq;

namespace Example.Repositories;
public class DogRepository
{
private static readonly List<Dog> _dogs = new()
{
new Dog { Breed = "Doberman" },
new Dog { Breed = "Pit Bull" },
new Dog { Breed = "German Shepard" }
};

public IEnumerable<Dog> GetDogs() => _dogs.AsEnumerable();
}
Loading