/// <inheritdoc />
        public bool Link <TChildType, TBaseType>()
            where TChildType : TBaseType
        {
            WireDataContractBaseLinkAttribute linkAttribute =
                typeof(TChildType).GetTypeInfo().GetCustomAttribute <WireDataContractBaseLinkAttribute>(false);

            //Have to make sure link is valid
            //Without link attribute we can't know how to register it.
            if (linkAttribute == null)
            {
                throw new InvalidOperationException($"Tried to link Child: {typeof(TChildType).FullName} with Base: {typeof(TBaseType).FullName} but no {nameof(WireDataContractBaseLinkAttribute)} attribute is marked on child.");
            }

            RegisterType <TChildType>();

            return(Link(linkAttribute, typeof(TBaseType), typeof(TChildType)));
        }
        private bool Link(WireDataContractBaseLinkAttribute linkAttribute, Type baseType, Type childType)
        {
            if (serializerStorageService.HasSerializerFor(baseType))
            {
                try
                {
                    (serializerStorageService.Get(baseType) as IRuntimePolymorphicRegisterable)
                    .TryLink(childType, linkAttribute.Index);

                    return(true);
                }
                catch (Exception e)
                {
                    throw new InvalidOperationException($"Unable to link type {baseType.Name} and {childType.Name}.", e);
                }
            }

            return(false);
        }
        /// <inheritdoc />
        public bool RegisterType <TTypeToRegister>()
        {
            //Ingoring all but wiretypes makes this a lot easier.
            if (typeof(TTypeToRegister).GetTypeInfo().GetCustomAttribute <WireDataContractAttribute>(true) == null)
            {
                throw new InvalidOperationException($"Do not register any type that isn't marked with {nameof(WireDataContractAttribute)}. Only register WireDataContracts too; contained types will be registered automatically.");
            }

            bool result = true;

            //Check if it requires runtime linking
            if (typeof(TTypeToRegister).GetTypeInfo().GetCustomAttribute <WireDataContractBaseLinkAttribute>(false) != null)
            {
                WireDataContractBaseLinkAttribute linkAttribute = typeof(TTypeToRegister).GetTypeInfo().GetCustomAttribute <WireDataContractBaseLinkAttribute>(false);

                //Only link if they provided a basetype.
                //Users may call RegisterType before linking so don't throw
                if (linkAttribute.BaseType != null)
                {
                    if (!serializerStorageService.HasSerializerFor(linkAttribute.BaseType))
                    {
                        RegisterType(linkAttribute.BaseType);
                    }

                    result = result && Link(linkAttribute, linkAttribute.BaseType, typeof(TTypeToRegister));
                }
            }

            if (!result)
            {
                return(false);
            }
            ITypeSerializerStrategy <TTypeToRegister> serializer = GetTypeSerializerStrategyForType <TTypeToRegister>();

            //Return the serializer; callers shouldn't need it though
            return(serializer != null && result);
        }