Interface IMessagePackConverterFactory
- Namespace
- Nerdbank.MessagePack
- Assembly
- Nerdbank.MessagePack.dll
A factory for MessagePackConverter<T> objects of arbitrary types.
public interface IMessagePackConverterFactory
Examples
A non-generic implementation of this interface is preferred when possible.
internal class NonGenericCustomConverterFactory : IMessagePackConverterFactory
{
// special purpose factory knows exactly what it supports. No generic type parameter needed.
public MessagePackConverter? CreateConverter(Type type, ITypeShape? shape, in ConverterContext context)
=> type == typeof(List<Guid>) ? new WrapInArrayConverter<List<Guid>>() : null;
}
When a generic context is required, implement ITypeShapeFunc on the same class and invoke into it after appropriate type checks.
internal class GenericCustomConverterFactory : IMessagePackConverterFactory, ITypeShapeFunc
{
// perform type check, then defer to generic method.
public MessagePackConverter? CreateConverter(Type type, ITypeShape? shape, in ConverterContext context)
=> shape?.Type == typeof(int) ? this.Invoke(shape) : null;
// type check is already done, just create the converter.
object? ITypeShapeFunc.Invoke<T>(ITypeShape<T> typeShape, object? state)
=> new WrapInArrayConverter<T>();
}
When generic type parameters are required for sub-elements of the type to be converted (e.g. the element type of a collection), you can leverage a TypeShapeVisitor implementation to obtain the generic type parameters.
internal class VisitorCustomConverterFactory : IMessagePackConverterFactory
{
// perform type check, then defer to generic method.
public MessagePackConverter? CreateConverter(Type type, ITypeShape? shape, in ConverterContext context)
=> shape is IEnumerableTypeShape enumShape && enumShape.Type.GetGenericTypeDefinition() == typeof(List<>) ?
(MessagePackConverter?)shape.Accept(Visitor.Instance) : null;
private class Visitor : TypeShapeVisitor
{
internal static readonly Visitor Instance = new();
public override object? VisitEnumerable<TEnumerable, TElement>(IEnumerableTypeShape<TEnumerable, TElement> enumerableShape, object? state = null)
=> new CustomListConverter<TElement>();
}
}
Methods
CreateConverter(Type, ITypeShape?, in ConverterContext)
Creates a converter for the given type if this factory is capable of it.
MessagePackConverter? CreateConverter(Type type, ITypeShape? shape, in ConverterContext context)
Parameters
typeTypeThe type to be serialized.
shapeITypeShapeThe shape of the type to be serialized, if available. The shape will typically be available. The only known exception is when the type has a PolyType marshaler defined.
contextConverterContextThe context in which this factory is being invoked. Provides access to other converters that may be required by the requested converter.
Returns
- MessagePackConverter
The converter for the data type, or null.
Remarks
Implementations that require a generic type parameter for the type to be converted should also implement ITypeShapeFunc with an Invoke<T>(ITypeShape<T>, object) method that creates the converter. The implementation of this method should perform any type checks necessary to determine whether this factory applies to the given shape, and if so, call Invoke<T>(T, ITypeShape, object?) to forward the call to the generic Invoke<T>(ITypeShape<T>, object) method defined on that same class.