Table of Contents

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(ITypeShape shape)
        => shape.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(ITypeShape shape)
        => 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(ITypeShape shape)
        => 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(ITypeShape)

Creates a converter for the given type if this factory is capable of it.

MessagePackConverter? CreateConverter(ITypeShape shape)

Parameters

shape ITypeShape

The shape of the type to be serialized.

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) to forward the call to the generic Invoke<T>(ITypeShape<T>, object) method defined on that same class.