using MessagePack.Formatters; using System; using System.Reflection; namespace MessagePack.Resolvers { public sealed class CompositeResolver : IFormatterResolver { public static readonly CompositeResolver Instance = new CompositeResolver(); static bool isFreezed = false; static IMessagePackFormatter[] formatters = new IMessagePackFormatter[0]; static IFormatterResolver[] resolvers = new IFormatterResolver[0]; CompositeResolver() { } public static void Register(params IFormatterResolver[] resolvers) { if (isFreezed) { throw new InvalidOperationException("Register must call on startup(before use GetFormatter)."); } CompositeResolver.resolvers = resolvers; } public static void Register(params IMessagePackFormatter[] formatters) { if (isFreezed) { throw new InvalidOperationException("Register must call on startup(before use GetFormatter)."); } CompositeResolver.formatters = formatters; } public static void Register(IMessagePackFormatter[] formatters, IFormatterResolver[] resolvers) { if (isFreezed) { throw new InvalidOperationException("Register must call on startup(before use GetFormatter)."); } CompositeResolver.resolvers = resolvers; CompositeResolver.formatters = formatters; } public static void RegisterAndSetAsDefault(params IFormatterResolver[] resolvers) { Register(resolvers); MessagePack.MessagePackSerializer.SetDefaultResolver(CompositeResolver.Instance); } public static void RegisterAndSetAsDefault(params IMessagePackFormatter[] formatters) { Register(formatters); MessagePack.MessagePackSerializer.SetDefaultResolver(CompositeResolver.Instance); } public static void RegisterAndSetAsDefault(IMessagePackFormatter[] formatters, IFormatterResolver[] resolvers) { Register(formatters); Register(resolvers); MessagePack.MessagePackSerializer.SetDefaultResolver(CompositeResolver.Instance); } public IMessagePackFormatter GetFormatter() { return FormatterCache.formatter; } static class FormatterCache { public static readonly IMessagePackFormatter formatter; static FormatterCache() { isFreezed = true; foreach (var item in formatters) { foreach (var implInterface in item.GetType().GetTypeInfo().ImplementedInterfaces) { var ti = implInterface.GetTypeInfo(); if (ti.IsGenericType && ti.GenericTypeArguments[0] == typeof(T)) { formatter = (IMessagePackFormatter)item; return; } } } foreach (var item in resolvers) { var f = item.GetFormatter(); if (f != null) { formatter = f; return; } } } } } }