private SurrogateTypeDescriberBuilder(ITypeDescriber typeDescribe, ITypeDescriber fallback, SurrogateTypeDescriberFallbackBehavior behavior, ImmutableDictionary <TypeInfo, TypeInfo> .Builder types)
        {
            TypeDescriber         = typeDescribe;
            FallbackTypeDescriber = fallback;
            FallbackBehavior      = behavior;

            SurrogateTypes = types;
        }
        // modify

        /// <summary>
        /// Sets the behavior to fallback to when no surrogate type has been registered.
        /// </summary>
        public SurrogateTypeDescriberBuilder WithFallbackBehavior(SurrogateTypeDescriberFallbackBehavior fallbackBehavior)
        {
            if (!Enum.IsDefined(Types.SurrogateTypeDescriberFallbackBehavior, fallbackBehavior))
            {
                Throw.ArgumentException($"Unexpected {nameof(SurrogateTypeDescriberFallbackBehavior)}: {fallbackBehavior}", nameof(fallbackBehavior));
            }

            FallbackBehavior = fallbackBehavior;

            return(this);
        }
        /// <summary>
        /// Creates a SurrogateTypeDescriberBuilder with the given fallback behavior, type describer, and fallback type describer.
        ///
        /// Uses the given ITypeDescriber to describes surrogates,
        ///   and falls back to provided fallback if no surrogate is registered and the provided SurrogateTypeDescriberFallbackBehavior
        ///   allows it.
        /// </summary>
        public static SurrogateTypeDescriberBuilder CreateBuilder(SurrogateTypeDescriberFallbackBehavior fallbackBehavior, ITypeDescriber typeDescriber, ITypeDescriber fallbackTypeDescriber)
        {
            if (!Enum.IsDefined(Types.SurrogateTypeDescriberFallbackBehavior, fallbackBehavior))
            {
                Throw.ArgumentException($"Unexpected {nameof(SurrogateTypeDescriberFallbackBehavior)}: {fallbackBehavior}", nameof(fallbackBehavior));
            }

            Utils.CheckArgumentNull(typeDescriber, nameof(typeDescriber));
            Utils.CheckArgumentNull(fallbackTypeDescriber, nameof(fallbackTypeDescriber));

            var inner = ImmutableDictionary.CreateBuilder <TypeInfo, TypeInfo>();

            return(new SurrogateTypeDescriberBuilder(typeDescriber, fallbackTypeDescriber, fallbackBehavior, inner));
        }
 /// <summary>
 /// Creates a SurrogateTypeDescriberBuilder with the given fallback behavior and type describer.
 ///
 /// Uses the given ITypeDescriber to describes surrogates,
 ///   and falls back to TypeDescriber.Default if no surrogate is registered if the provided SurrogateTypeDescriberFallbackBehavior
 ///   allows it.
 /// </summary>
 public static SurrogateTypeDescriberBuilder CreateBuilder(SurrogateTypeDescriberFallbackBehavior fallbackBehavior, ITypeDescriber typeDescriber)
 => CreateBuilder(fallbackBehavior, typeDescriber, TypeDescribers.Default);
 /// <summary>
 /// Creates a SurrogateTypeDescriberBuilder with the given fallback behavior, type describer, and fallback type describer.
 ///
 /// Uses the given ITypeDescriber to describes surrogates,
 ///   and falls back to provided fallback if no surrogate is registered and the provided SurrogateTypeDescriberFallbackBehavior
 ///   allows it.
 /// </summary>
 public static SurrogateTypeDescriberBuilder CreateBuilder(SurrogateTypeDescriberFallbackBehavior fallbackBehavior, ITypeDescriber typeDescriber, ITypeDescriber fallbackTypeDescriber)
 => SurrogateTypeDescriberBuilder.CreateBuilder(fallbackBehavior, typeDescriber, fallbackTypeDescriber);
        internal SurrogateTypeDescriber(ITypeDescriber typeDescriber, ITypeDescriber fallback, SurrogateTypeDescriberFallbackBehavior fallbackBehavior, ImmutableDictionary <TypeInfo, TypeInfo> surrogateTypes)
        {
            SurrogateTypes    = surrogateTypes;
            TypeDescriber     = typeDescriber;
            FallbackDescriber = fallback;

            switch (fallbackBehavior)
            {
            case SurrogateTypeDescriberFallbackBehavior.Throw:
                ThrowOnNoRegisteredSurrogate = true;
                break;

            case SurrogateTypeDescriberFallbackBehavior.UseFallback:
                ThrowOnNoRegisteredSurrogate = false;
                break;

            default:
                Throw.ImpossibleException($"Unexpected {nameof(SurrogateTypeDescriberFallbackBehavior)}: {fallbackBehavior}");
                break;
            }
        }