Особенности загрузки карточек
Особенности загрузки карточек¶
В клиентском расширении иногда есть смысл загрузить другую карточку, например, карточку-сателлит.
using System;
using System.Threading.Tasks;
using Tessa.Cards;
using Tessa.Cards.Extensions;
public sealed class SomeExtension : CardGetExtension
{
public SomeExtension(ICardRepository cardRepository)
{
this.cardRepository = cardRepository;
}
private readonly ICardRepository cardRepository;
public override async Task AfterRequest(ICardGetExtensionContext context)
{
var response = await this.cardRepository.GetAsync(new CardGetRequest { CardID = ... }, context.CancellationToken);
var satelliteCard = response.Card;
// используем загруженную satelliteCard
}
}
Регистрируем расширение:
extensionContainer
.RegisterExtension<ICardGetExtension, SomeExtension>(x => x
.WithOrder(ExtensionStage.AfterPlatform, 1)
.WithUnity(unityContainer
.RegisterType<SomeExtension>(
new ContainerControlledLifetimeManager())));
При этом в момент выполнения загрузки основной карточки резолвится расширение SomeExtension, которому в конструктор передаётся ICardRepository вместе с расширениями. Именно он и используется в методе AfterRequest.
По умолчанию не выполняется расширение по сжатию пакета карточки. Поэтому в satelliteCard приходит карточка с несжатым пакетом, которую можно использовать без распаковки методом CardHelper.Decompress(satelliteCard). Сжата карточка или нет можно точно узнать, проверив булевское свойство response.Compressed. Для того, чтобы выполнялось сжатие, нужно включить сжатие в запросе, указав CompressionMode. На сервере этого делать нельзя, но на клиенте это рекомендуемая практика:
CardGetResponse response = await this.cardRepository.GetAsync(new CardGetRequest { CompressionMode = CardCompressionMode.Full, CardID = ... });
Card satelliteCard = response.Card;
Чтобы не использовать расширения при загрузке карточки, нужно получить ICardRepository без расширений. Для этого надо изменить регистрацию расширения:
extensionContainer
.RegisterExtension<ICardGetExtension, SomeExtension>(x => x
.WithOrder(ExtensionStage.AfterPlatform, 1)
.WithUnity(unityContainer
.RegisterType<SomeExtension>(
new ContainerControlledLifetimeManager(),
new InjectionConstructor(
new ResolvedParameter<ICardRepository>(
CardRepositoryNames.Default)))));
Следует проявить осторожность при использовании ICardRepository на сервере вместе с расширениями. Некоторые разработчики расширений ожидают, что в клиентских расширениях перед запросом выполняется подготовка к действию, а в клиентских расширениях после запроса выполняется некое изменение загруженной карточки, которое доступно только на клиенте. Если полностью вырезать клиентские расширения из этой цепочки, то можно ожидать непредсказуемое поведение. В платформенных расширениях такое есть только при явном указании сжатия карточки при загрузке на сервере, но в пользовательских расширениях может быть всё что угодно. Чтобы не выполнять пользовательские расширения, а выполнять только платформенные, надо указать при регистрации вашего расширения резолв ICardRepository по имени CardRepositoryNames.Platform. При этом при загрузке карточки на клиенте по-прежнему понадобится задать CompressionMode.
В примере выше при использовании компонента ICardGetComponent вместо ICardRepository также следует указывать имя CardRepositoryNames.Default при регистрации в Unity.