/// <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); }