Closed shoe-diamente closed 3 years ago
I used the following approach
// somewhere in the model
public CollectionModel<ProductLineModel> ProductLines { get; }
// generic type
[GenericName("{0}Collection")]
public class CollectionModel<TItem>
{
// my fields for collections paging
}
// custom attribute
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class GenericNameAttribute : MetaDataAttributeBase
{
private readonly string format;
/// <summary>
/// Creates initialized attribute instance.
/// </summary>
/// <param name="format">Name format. "{0}" will be replaced with name of generic type argument.</param>
public GenericNameAttribute(string format) => this.format = format;
/// <inheritdoc />
public override void MapType(GraphTypeInfo type, TypeInfo typeInfo)
{
var genericArg = typeInfo.GetGenericArguments().FirstOrDefault();
string itemName;
if (genericArg != null)
{
itemName = type.TypeResolver.DeriveType(genericArg.GetTypeInfo()).Name;
if (!itemName.EndsWith("s"))
itemName += 's';
}
else
{
itemName = "Base";
}
type.Name = format.FormatWith(itemName);
}
}
Sometimes it's useful to be able to define something like
Type<OtherType>
and use it as a GraphQL type. The GraphQL specification doesn't allow templated types, but with the originalgraphql-dotnet
library you can use something like:to achieve the expected effect of having
Type<OtherType>
andType<SomeOtherType>
beOtherTypeType
andSomeOtherTypeType
respectively.With
graphql-dotnet/conventions
though you seem not to be able define the name as expected because:would return always "OtherType" and not the underlying type. While:
is not a constant expression and therefore cannot be used in the attribute.
Are there any other ways to achieve a similar effect?