// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
namespace Microsoft.Teams.Apps.State;
///
/// Holds the conversation-scoped and user-scoped state for the current turn.
///
public sealed class TurnStateContainer
{
private Func? _deleteDelegate;
///
/// Gets the conversation-scoped state, shared by all users in the conversation.
/// Keyed by Conversation.Id.
///
public TurnState ConversationState { get; }
///
/// Gets the user-scoped state, private to each user in each conversation.
/// Keyed by Conversation.Id + From.Id.
/// Returns when the activity has no From field.
///
public TurnState? UserState { get; }
///
/// Initializes a new instance of the class.
///
public TurnStateContainer(TurnState conversationState, TurnState? userState)
{
ArgumentNullException.ThrowIfNull(conversationState);
ConversationState = conversationState;
UserState = userState;
}
///
/// Sets the delegate used to delete state from the backing store.
/// Called by the framework after loading state.
///
internal void SetDeleteDelegate(Func deleteDelegate)
{
_deleteDelegate = deleteDelegate;
}
///
/// Deletes conversation and user state from the backing store.
/// The in-memory state remains accessible for the rest of the turn
/// but will not be persisted at end-of-turn unless new values are written.
///
/// A cancellation token.
public async Task DeleteAsync(CancellationToken cancellationToken = default)
{
if (_deleteDelegate is null)
{
throw new InvalidOperationException(
"State deletion is not available. Call UseState() during service registration.");
}
await _deleteDelegate(cancellationToken).ConfigureAwait(false);
// Clear dirty flags so end-of-turn save doesn't re-persist the deleted state.
ConversationState.IsDirty = false;
if (UserState is not null)
{
UserState.IsDirty = false;
}
}
}