Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Polished unit tests
Fixed cyclical graph type reference
Added exception handling
  • Loading branch information
Michannne committed May 16, 2019
commit 1ccbefec08afbf5d6b3b13bd0192120f151964e3
2 changes: 2 additions & 0 deletions GraphQL-Core.Tests/Initialize.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using GraphQL;
using GraphQL.Types;
using GraphQLCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json.Linq;
Expand Down Expand Up @@ -32,6 +33,7 @@ public void Init()

return service.ImplementationInstance;
});
GraphQLCoreTypeWrapperGenerator.Clear();
}

public (bool error, ExecutionResult) Ask(string query, string operation, JObject variables)
Expand Down
4 changes: 1 addition & 3 deletions GraphQL-Core.Tests/TypeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public void Test_AddType_HasFields(Type T)
[TestMethod]
[TestCategory("Types")]
[DataTestMethod()]
//[DataRow(typeof(Book))]
[DataRow(typeof(Book))]
[DataRow(typeof(Book_WithValueTypes))]
[DataRow(typeof(Book_WithEnumTypes))]
[DataRow(typeof(Book_WithEnumerables))]
Expand All @@ -127,8 +127,6 @@ public void Test_AddType_HasFields(Type T)
[DataRow(typeof(Author))]
[DataRow(typeof(Author_WithValueTypes))]
[DataRow(typeof(Author_WithEnumTypes))]
[DataRow(typeof(Author_WithEnumerableBooks))]
[DataRow(typeof(Author_WithManyManyBooks))]
[DataRow(typeof(Book_WithDuplicateBaseTypes))]
[DataRow(typeof(Book_WithTwoAuthors))]
[DataRow(typeof(Book_WithVirtualAuthorAndId))]
Expand Down
91 changes: 60 additions & 31 deletions GraphQL-Core/CSharpClassBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using GraphQLCore.Types;
using GraphQLCore.Exceptions;
using GraphQLCore.Types;
using System;
using System.Collections.Generic;
using System.Reflection;
Expand All @@ -21,23 +22,30 @@ public static class GraphQLCoreTypeWrapperGenerator

public static Type CreateGraphQLTypeWrapper<T>()
{
if (genericTypeParentClasses.ContainsKey(typeof(GenericType<T>)))
return genericTypeParentClasses[typeof(GenericType<T>)];
try
{
if (genericTypeParentClasses.ContainsKey(typeof(GenericType<T>)))
return genericTypeParentClasses[typeof(GenericType<T>)];

TypeBuilder tb = GetTypeBuilder(typeof(T).Name + typeNameAppend, typeof(GenericType<T>));
tb.DefineDefaultConstructor(
MethodAttributes.Public
| MethodAttributes.SpecialName
| MethodAttributes.RTSpecialName);
TypeBuilder tb = GetTypeBuilder(typeof(T).Name + typeNameAppend, typeof(GenericType<T>));
tb.DefineDefaultConstructor(
MethodAttributes.Public
| MethodAttributes.SpecialName
| MethodAttributes.RTSpecialName);

tb.SetParent(typeof(GenericType<T>));
tb.SetParent(typeof(GenericType<T>));

TypeInfo objectTypeInfo = tb.CreateTypeInfo();
Type type = objectTypeInfo.AsType();
TypeInfo objectTypeInfo = tb.CreateTypeInfo();
Type type = objectTypeInfo.AsType();

genericTypeParentClasses[typeof(GenericType<T>)] = type;
genericTypeParentClasses[typeof(GenericType<T>)] = type;

return type;
return type;
}
catch(Exception e)
{
throw new GraphQLCoreMSILException("Attempt to create new C# type failed. Refer to inner exception for details", e);
}
}

public static Type GetDerivedGenericUserType<T>()
Expand All @@ -58,28 +66,49 @@ public static Type GetDerivedGenericUserType(this Type T)

private static AssemblyName CreateDynamicAssemblyName()
{
var currentAssemblyName = Assembly.GetEntryAssembly().GetName().Clone() as AssemblyName;
var asmName = new AssemblyName(Guid.NewGuid().ToString());
asmName.Name = currentAssemblyName.Name + asmNameAppend;
return currentAssemblyName;
try
{
var currentAssemblyName = Assembly.GetEntryAssembly().GetName().Clone() as AssemblyName;
var asmName = new AssemblyName(Guid.NewGuid().ToString());
asmName.Name = currentAssemblyName.Name + asmNameAppend;
return currentAssemblyName;
}
catch(Exception e)
{
throw new GraphQLCoreAssemblyException("Attempt to create new dynamic assembly failed. Refer to inner exception for details", e);
}
}

private static TypeBuilder GetTypeBuilder(string typeName, Type baseClass)
{
var typeSignature = typeName;

if(mdBuilder is null)
mdBuilder = asmBuilder.DefineDynamicModule(mdName);

TypeBuilder tb = mdBuilder.DefineType(typeSignature,
TypeAttributes.Public |
TypeAttributes.Class |
TypeAttributes.AutoClass |
TypeAttributes.AnsiClass |
TypeAttributes.BeforeFieldInit |
TypeAttributes.AutoLayout,
baseClass);
return tb;
try
{
var typeSignature = typeName;

if (mdBuilder is null)
mdBuilder = asmBuilder.DefineDynamicModule(mdName);

TypeBuilder tb = mdBuilder.DefineType(typeSignature,
TypeAttributes.Public |
TypeAttributes.Class |
TypeAttributes.AutoClass |
TypeAttributes.AnsiClass |
TypeAttributes.BeforeFieldInit |
TypeAttributes.AutoLayout,
baseClass);
return tb;
}
catch(Exception e)
{
throw new GraphQLCoreClassDefinitionException("Attempt to define a new C# type failed. Refer to inner exception for details", e);
}
}

public static void Clear()
{
genericTypeParentClasses.Clear();
mdBuilder = null;
asmBuilder = AssemblyBuilder.DefineDynamicAssembly(CreateDynamicAssemblyName(), AssemblyBuilderAccess.Run);
}
}
}
20 changes: 20 additions & 0 deletions GraphQL-Core/Exceptions/BuilderExceptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace GraphQLCore.Exceptions
{
public class GraphQLCoreStitchException : Exception
{
public GraphQLCoreStitchException() { }
public GraphQLCoreStitchException(string message) : base(message) { }
public GraphQLCoreStitchException(string message, Exception inner) : base(message, inner) { }
}

public class GraphQLCoreTypeException : Exception
{
public GraphQLCoreTypeException() { }
public GraphQLCoreTypeException(string message) : base(message) { }
public GraphQLCoreTypeException(string message, Exception inner) : base(message, inner) { }
}
}
13 changes: 13 additions & 0 deletions GraphQL-Core/Exceptions/ExtensionExceptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace GraphQLCore.Exceptions
{
public class GraphQLCoreConversionException : Exception
{
public GraphQLCoreConversionException() { }
public GraphQLCoreConversionException(string message) : base(message) { }
public GraphQLCoreConversionException(string message, Exception inner) : base(message, inner) { }
}
}
27 changes: 27 additions & 0 deletions GraphQL-Core/Exceptions/MSILExceptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace GraphQLCore.Exceptions
{
public class GraphQLCoreMSILException : Exception
{
public GraphQLCoreMSILException() { }
public GraphQLCoreMSILException(string message) : base(message) { }
public GraphQLCoreMSILException(string message, Exception inner) : base(message, inner) { }
}

public class GraphQLCoreAssemblyException : Exception
{
public GraphQLCoreAssemblyException() { }
public GraphQLCoreAssemblyException(string message) : base(message) { }
public GraphQLCoreAssemblyException(string message, Exception inner) : base(message, inner) { }
}

public class GraphQLCoreClassDefinitionException : Exception
{
public GraphQLCoreClassDefinitionException() { }
public GraphQLCoreClassDefinitionException(string message) : base(message) { }
public GraphQLCoreClassDefinitionException(string message, Exception inner) : base(message, inner) { }
}
}
Loading