// Copyright (c) Arlo Godfrey. All Rights Reserved. // Licensed under the GNU Lesser General Public License, Version 3.0 with additional terms. // See the LICENSE, LICENSE.LESSER and LICENSE.ADDITIONAL files in the project root for more information. using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using OwlCore.ComponentModel; using OwlCore.Events; using StrixMusic.Sdk.AdapterModels; using StrixMusic.Sdk.AppModels; using StrixMusic.Sdk.CoreModels; using StrixMusic.Sdk.MediaPlayback; namespace StrixMusic.Sdk.Plugins.Model { /// /// An implementation of which delegates all member access to the implementation, /// unless the member is overridden in a derived class which changes the behavior. /// public class PlayableCollectionGroupPluginBase : IModelPlugin, IPlayableCollectionGroup, IDelegatable { /// /// Creates a new instance of . /// /// Metadata about the plugin which was provided during registration. /// The implementation which all member access is delegated to, unless the member is overridden in a derived class which changes the behavior. internal protected PlayableCollectionGroupPluginBase(ModelPluginMetadata registration, IPlayableCollectionGroup inner) { Metadata = registration; Inner = inner; InnerArtistCollection = inner; InnerAlbumCollection = inner; InnerPlaylistCollection = inner; InnerTrackCollection = inner; InnerImageCollection = inner; InnerUrlCollection = inner; InnerPlayable = inner; InnerDownloadable = inner; } /// /// Metadata about the plugin which was provided during registration. /// public ModelPluginMetadata Metadata { get; } /// public IPlayableCollectionGroup Inner { get; set; } /// /// A wrapped implementation which member access can be delegated to. Defaults to . /// public IPlayable InnerPlayable { get; set; } /// /// A wrapped implementation which member access can be delegated to. Defaults to . /// public IDownloadable InnerDownloadable { get; set; } /// /// A wrapped implementation which member access can be delegated to. Defaults to . /// public IArtistCollection InnerArtistCollection { get; set; } /// /// A wrapped implementation which member access can be delegated to. Defaults to . /// public IAlbumCollection InnerAlbumCollection { get; set; } /// /// A wrapped implementation which member access can be delegated to. Defaults to . /// public IPlaylistCollection InnerPlaylistCollection { get; set; } /// /// A wrapped implementation which member access can be delegated to. Defaults to . /// public ITrackCollection InnerTrackCollection { get; set; } /// /// A wrapped implementation which member access can be delegated to. Defaults to . /// public IImageCollection InnerImageCollection { get; set; } /// /// A wrapped implementation which member access can be delegated to. Defaults to . /// public IUrlCollection InnerUrlCollection { get; set; } /// public event EventHandler? SourcesChanged { add => Inner.SourcesChanged += value; remove => Inner.SourcesChanged -= value; } /// public virtual DownloadInfo DownloadInfo => InnerDownloadable.DownloadInfo; /// public virtual Task StartDownloadOperationAsync(DownloadOperation operation, CancellationToken cancellationToken = default) => InnerDownloadable.StartDownloadOperationAsync(operation, cancellationToken); /// public virtual event EventHandler? DownloadInfoChanged { add => InnerDownloadable.DownloadInfoChanged += value; remove => InnerDownloadable.DownloadInfoChanged -= value; } /// public virtual int TotalUrlCount => InnerUrlCollection.TotalUrlCount; /// public virtual Task RemoveUrlAsync(int index, CancellationToken cancellationToken = default) => InnerUrlCollection.RemoveUrlAsync(index, cancellationToken); /// public virtual Task IsAddUrlAvailableAsync(int index, CancellationToken cancellationToken = default) => InnerUrlCollection.IsAddUrlAvailableAsync(index, cancellationToken); /// public virtual Task IsRemoveUrlAvailableAsync(int index, CancellationToken cancellationToken = default) => InnerUrlCollection.IsRemoveUrlAvailableAsync(index, cancellationToken); /// public virtual event EventHandler? UrlsCountChanged { add => InnerUrlCollection.UrlsCountChanged += value; remove => InnerUrlCollection.UrlsCountChanged -= value; } /// public virtual bool Equals(ICoreUrlCollection other) => InnerUrlCollection.Equals(other); /// IReadOnlyList IMerged.Sources => ((IMerged)Inner).Sources; /// IReadOnlyList IMerged.Sources => InnerImageCollection.Sources; /// IReadOnlyList IMerged.Sources => ((IMerged)InnerTrackCollection).Sources; /// IReadOnlyList IMerged.Sources => ((IMerged)InnerArtistCollection).Sources; /// IReadOnlyList IMerged.Sources => ((IMerged)InnerArtistCollection).Sources; /// IReadOnlyList IMerged.Sources => ((IMerged)InnerAlbumCollection).Sources; /// IReadOnlyList IMerged.Sources => ((IMerged)InnerAlbumCollection).Sources; /// IReadOnlyList IMerged.Sources => ((IMerged)Inner).Sources; /// IReadOnlyList IMerged.Sources => ((IMerged)Inner).Sources; /// IReadOnlyList IMerged.Sources => ((IMerged)Inner).Sources; /// public IReadOnlyList Sources => ((IMerged)Inner).Sources; /// public virtual IAsyncEnumerable GetUrlsAsync(int limit, int offset, CancellationToken cancellationToken = default) => InnerUrlCollection.GetUrlsAsync(limit, offset, cancellationToken); /// public virtual Task AddUrlAsync(IUrl url, int index, CancellationToken cancellationToken = default) => InnerUrlCollection.AddUrlAsync(url, index, cancellationToken); /// public virtual event CollectionChangedEventHandler? UrlsChanged { add => InnerUrlCollection.UrlsChanged += value; remove => InnerUrlCollection.UrlsChanged -= value; } /// public virtual Task IsAddImageAvailableAsync(int index, CancellationToken cancellationToken = default) => InnerImageCollection.IsAddImageAvailableAsync(index, cancellationToken); /// public virtual Task IsRemoveImageAvailableAsync(int index, CancellationToken cancellationToken = default) => InnerImageCollection.IsRemoveImageAvailableAsync(index, cancellationToken); /// public virtual Task RemoveImageAsync(int index, CancellationToken cancellationToken = default) => InnerImageCollection.RemoveImageAsync(index, cancellationToken); /// public virtual int TotalImageCount => InnerImageCollection.TotalImageCount; /// public virtual event EventHandler? ImagesCountChanged { add => InnerImageCollection.ImagesCountChanged += value; remove => InnerImageCollection.ImagesCountChanged -= value; } /// public virtual bool Equals(ICoreImageCollection other) => InnerImageCollection.Equals(other); /// public virtual IAsyncEnumerable GetImagesAsync(int limit, int offset, CancellationToken cancellationToken = default) => InnerImageCollection.GetImagesAsync(limit, offset, cancellationToken); /// public virtual Task AddImageAsync(IImage image, int index, CancellationToken cancellationToken = default) => InnerImageCollection.AddImageAsync(image, index, cancellationToken); /// public virtual event CollectionChangedEventHandler? ImagesChanged { add => InnerImageCollection.ImagesChanged += value; remove => InnerImageCollection.ImagesChanged -= value; } /// public virtual string Id => InnerPlayable.Id; /// public virtual string Name => InnerPlayable.Name; /// public virtual string? Description => InnerPlayable.Description; /// public virtual DateTime? LastPlayed => InnerPlayable.LastPlayed; /// public virtual PlaybackState PlaybackState => InnerPlayable.PlaybackState; /// public virtual TimeSpan Duration => InnerPlayable.Duration; /// public virtual bool IsChangeNameAsyncAvailable => InnerPlayable.IsChangeNameAsyncAvailable; /// public virtual bool IsChangeDescriptionAsyncAvailable => InnerPlayable.IsChangeDescriptionAsyncAvailable; /// public virtual bool IsChangeDurationAsyncAvailable => InnerPlayable.IsChangeDurationAsyncAvailable; /// public virtual Task ChangeNameAsync(string name, CancellationToken cancellationToken = default) => InnerPlayable.ChangeNameAsync(name, cancellationToken); /// public virtual Task ChangeDescriptionAsync(string? description, CancellationToken cancellationToken = default) => InnerPlayable.ChangeDescriptionAsync(description, cancellationToken); /// public virtual Task ChangeDurationAsync(TimeSpan duration, CancellationToken cancellationToken = default) => InnerPlayable.ChangeDurationAsync(duration, cancellationToken); /// public virtual event EventHandler? PlaybackStateChanged { add => InnerPlayable.PlaybackStateChanged += value; remove => InnerPlayable.PlaybackStateChanged -= value; } /// public virtual event EventHandler? NameChanged { add => InnerPlayable.NameChanged += value; remove => InnerPlayable.NameChanged -= value; } /// public virtual event EventHandler? DescriptionChanged { add => InnerPlayable.DescriptionChanged += value; remove => InnerPlayable.DescriptionChanged -= value; } /// public virtual event EventHandler? DurationChanged { add => InnerPlayable.DurationChanged += value; remove => InnerPlayable.DurationChanged -= value; } /// public virtual event EventHandler? LastPlayedChanged { add => InnerPlayable.LastPlayedChanged += value; remove => InnerPlayable.LastPlayedChanged -= value; } /// public virtual event EventHandler? IsChangeNameAsyncAvailableChanged { add => InnerPlayable.IsChangeNameAsyncAvailableChanged += value; remove => InnerPlayable.IsChangeNameAsyncAvailableChanged -= value; } /// public virtual event EventHandler? IsChangeDescriptionAsyncAvailableChanged { add => InnerPlayable.IsChangeDescriptionAsyncAvailableChanged += value; remove => InnerPlayable.IsChangeDescriptionAsyncAvailableChanged -= value; } /// public virtual event EventHandler? IsChangeDurationAsyncAvailableChanged { add => InnerPlayable.IsChangeDurationAsyncAvailableChanged += value; remove => InnerPlayable.IsChangeDurationAsyncAvailableChanged -= value; } /// public virtual DateTime? AddedAt => Inner.AddedAt; /// public virtual int TotalTrackCount => InnerTrackCollection.TotalTrackCount; /// public virtual bool IsPlayTrackCollectionAsyncAvailable => InnerTrackCollection.IsPlayTrackCollectionAsyncAvailable; /// public virtual bool IsPauseTrackCollectionAsyncAvailable => InnerTrackCollection.IsPauseTrackCollectionAsyncAvailable; /// public virtual Task PlayTrackCollectionAsync(CancellationToken cancellationToken = default) => InnerTrackCollection.PlayTrackCollectionAsync(cancellationToken); /// public virtual Task PauseTrackCollectionAsync(CancellationToken cancellationToken = default) => InnerTrackCollection.PauseTrackCollectionAsync(cancellationToken); /// public virtual Task RemoveTrackAsync(int index, CancellationToken cancellationToken = default) => InnerTrackCollection.RemoveTrackAsync(index, cancellationToken); /// public virtual Task IsAddTrackAvailableAsync(int index, CancellationToken cancellationToken = default) => InnerTrackCollection.IsAddTrackAvailableAsync(index, cancellationToken); /// public virtual Task IsRemoveTrackAvailableAsync(int index, CancellationToken cancellationToken = default) => InnerTrackCollection.IsRemoveTrackAvailableAsync(index, cancellationToken); /// public virtual event EventHandler? IsPlayTrackCollectionAsyncAvailableChanged { add => InnerTrackCollection.IsPlayTrackCollectionAsyncAvailableChanged += value; remove => InnerTrackCollection.IsPlayTrackCollectionAsyncAvailableChanged -= value; } /// public virtual event EventHandler? IsPauseTrackCollectionAsyncAvailableChanged { add => InnerTrackCollection.IsPauseTrackCollectionAsyncAvailableChanged += value; remove => InnerTrackCollection.IsPauseTrackCollectionAsyncAvailableChanged -= value; } /// public virtual event EventHandler? TracksCountChanged { add => InnerTrackCollection.TracksCountChanged += value; remove => InnerTrackCollection.TracksCountChanged -= value; } /// public virtual bool Equals(ICoreTrackCollection other) => InnerTrackCollection.Equals(other); /// public virtual Task PlayTrackCollectionAsync(ITrack track, CancellationToken cancellationToken = default) => InnerTrackCollection.PlayTrackCollectionAsync(track, cancellationToken); /// public virtual IAsyncEnumerable GetTracksAsync(int limit, int offset, CancellationToken cancellationToken = default) => InnerTrackCollection.GetTracksAsync(limit, offset, cancellationToken); /// public virtual Task AddTrackAsync(ITrack track, int index, CancellationToken cancellationToken = default) => InnerTrackCollection.AddTrackAsync(track, index, cancellationToken); /// public virtual event CollectionChangedEventHandler? TracksChanged { add => InnerTrackCollection.TracksChanged += value; remove => InnerTrackCollection.TracksChanged -= value; } /// public virtual int TotalArtistItemsCount => InnerArtistCollection.TotalArtistItemsCount; /// public virtual bool IsPlayArtistCollectionAsyncAvailable => InnerArtistCollection.IsPlayArtistCollectionAsyncAvailable; /// public virtual bool IsPauseArtistCollectionAsyncAvailable => InnerArtistCollection.IsPauseArtistCollectionAsyncAvailable; /// public virtual Task PlayArtistCollectionAsync(CancellationToken cancellationToken = default) => InnerArtistCollection.PlayArtistCollectionAsync(cancellationToken); /// public virtual Task PauseArtistCollectionAsync(CancellationToken cancellationToken = default) => InnerArtistCollection.PauseArtistCollectionAsync(cancellationToken); /// public virtual Task RemoveArtistItemAsync(int index, CancellationToken cancellationToken = default) => InnerArtistCollection.RemoveArtistItemAsync(index, cancellationToken); /// /// public virtual Task IsAddArtistItemAvailableAsync(int index, CancellationToken cancellationToken = default) => InnerArtistCollection.IsAddArtistItemAvailableAsync(index, cancellationToken); /// public virtual Task IsRemoveArtistItemAvailableAsync(int index, CancellationToken cancellationToken = default) => InnerArtistCollection.IsRemoveArtistItemAvailableAsync(index, cancellationToken); /// public virtual event EventHandler? IsPlayArtistCollectionAsyncAvailableChanged { add => InnerArtistCollection.IsPlayArtistCollectionAsyncAvailableChanged += value; remove => InnerArtistCollection.IsPlayArtistCollectionAsyncAvailableChanged -= value; } /// public virtual event EventHandler? IsPauseArtistCollectionAsyncAvailableChanged { add => InnerArtistCollection.IsPauseArtistCollectionAsyncAvailableChanged += value; remove => InnerArtistCollection.IsPauseArtistCollectionAsyncAvailableChanged -= value; } /// public virtual event EventHandler? ArtistItemsCountChanged { add => InnerArtistCollection.ArtistItemsCountChanged += value; remove => InnerArtistCollection.ArtistItemsCountChanged -= value; } /// public virtual bool Equals(ICoreArtistCollectionItem other) => InnerArtistCollection.Equals(other); /// public virtual bool Equals(ICoreArtistCollection other) => InnerArtistCollection.Equals(other); /// public virtual Task PlayArtistCollectionAsync(IArtistCollectionItem artistItem, CancellationToken cancellationToken = default) => InnerArtistCollection.PlayArtistCollectionAsync(artistItem, cancellationToken); /// public virtual IAsyncEnumerable GetArtistItemsAsync(int limit, int offset, CancellationToken cancellationToken = default) => InnerArtistCollection.GetArtistItemsAsync(limit, offset, cancellationToken); /// public virtual Task AddArtistItemAsync(IArtistCollectionItem artistItem, int index, CancellationToken cancellationToken = default) => InnerArtistCollection.AddArtistItemAsync(artistItem, index, cancellationToken); /// public virtual event CollectionChangedEventHandler? ArtistItemsChanged { add => InnerArtistCollection.ArtistItemsChanged += value; remove => InnerArtistCollection.ArtistItemsChanged -= value; } /// public virtual int TotalAlbumItemsCount => InnerAlbumCollection.TotalAlbumItemsCount; /// public virtual bool IsPlayAlbumCollectionAsyncAvailable => InnerAlbumCollection.IsPlayAlbumCollectionAsyncAvailable; /// public virtual bool IsPauseAlbumCollectionAsyncAvailable => InnerAlbumCollection.IsPauseAlbumCollectionAsyncAvailable; /// public virtual Task PlayAlbumCollectionAsync(CancellationToken cancellationToken = default) => InnerAlbumCollection.PlayAlbumCollectionAsync(cancellationToken); /// public virtual Task PauseAlbumCollectionAsync(CancellationToken cancellationToken = default) => InnerAlbumCollection.PauseAlbumCollectionAsync(cancellationToken); /// public virtual Task RemoveAlbumItemAsync(int index, CancellationToken cancellationToken = default) => InnerAlbumCollection.RemoveAlbumItemAsync(index, cancellationToken); /// public virtual Task IsAddAlbumItemAvailableAsync(int index, CancellationToken cancellationToken = default) => InnerAlbumCollection.IsAddAlbumItemAvailableAsync(index, cancellationToken); /// public virtual Task IsRemoveAlbumItemAvailableAsync(int index, CancellationToken cancellationToken = default) => InnerAlbumCollection.IsRemoveAlbumItemAvailableAsync(index, cancellationToken); /// public virtual event EventHandler? IsPlayAlbumCollectionAsyncAvailableChanged { add => InnerAlbumCollection.IsPlayAlbumCollectionAsyncAvailableChanged += value; remove => InnerAlbumCollection.IsPlayAlbumCollectionAsyncAvailableChanged -= value; } /// public virtual event EventHandler? IsPauseAlbumCollectionAsyncAvailableChanged { add => InnerAlbumCollection.IsPauseAlbumCollectionAsyncAvailableChanged += value; remove => InnerAlbumCollection.IsPauseAlbumCollectionAsyncAvailableChanged -= value; } /// public virtual event EventHandler? AlbumItemsCountChanged { add => InnerAlbumCollection.AlbumItemsCountChanged += value; remove => InnerAlbumCollection.AlbumItemsCountChanged -= value; } /// public virtual bool Equals(ICoreAlbumCollectionItem other) => InnerAlbumCollection.Equals(other); /// public virtual bool Equals(ICoreAlbumCollection other) => InnerAlbumCollection.Equals(other); /// public virtual Task PlayAlbumCollectionAsync(IAlbumCollectionItem albumItem, CancellationToken cancellationToken = default) => InnerAlbumCollection.PlayAlbumCollectionAsync(albumItem, cancellationToken); /// public virtual IAsyncEnumerable GetAlbumItemsAsync(int limit, int offset, CancellationToken cancellationToken = default) => InnerAlbumCollection.GetAlbumItemsAsync(limit, offset, cancellationToken); /// public virtual Task AddAlbumItemAsync(IAlbumCollectionItem album, int index, CancellationToken cancellationToken = default) => InnerAlbumCollection.AddAlbumItemAsync(album, index, cancellationToken); /// public virtual event CollectionChangedEventHandler? AlbumItemsChanged { add => InnerAlbumCollection.AlbumItemsChanged += value; remove => InnerAlbumCollection.AlbumItemsChanged -= value; } /// public virtual int TotalPlaylistItemsCount => InnerPlaylistCollection.TotalPlaylistItemsCount; /// public virtual bool IsPlayPlaylistCollectionAsyncAvailable => InnerPlaylistCollection.IsPlayPlaylistCollectionAsyncAvailable; /// public virtual bool IsPausePlaylistCollectionAsyncAvailable => InnerPlaylistCollection.IsPausePlaylistCollectionAsyncAvailable; /// public virtual Task PlayPlaylistCollectionAsync(CancellationToken cancellationToken = default) => InnerPlaylistCollection.PlayPlaylistCollectionAsync(cancellationToken); /// public virtual Task PausePlaylistCollectionAsync(CancellationToken cancellationToken = default) => InnerPlaylistCollection.PausePlaylistCollectionAsync(cancellationToken); /// public virtual Task RemovePlaylistItemAsync(int index, CancellationToken cancellationToken = default) => InnerPlaylistCollection.RemovePlaylistItemAsync(index, cancellationToken); /// public virtual Task IsAddPlaylistItemAvailableAsync(int index, CancellationToken cancellationToken = default) => InnerPlaylistCollection.IsAddPlaylistItemAvailableAsync(index, cancellationToken); /// public virtual Task IsRemovePlaylistItemAvailableAsync(int index, CancellationToken cancellationToken = default) => InnerPlaylistCollection.IsRemovePlaylistItemAvailableAsync(index, cancellationToken); /// public virtual event EventHandler? IsPlayPlaylistCollectionAsyncAvailableChanged { add => InnerPlaylistCollection.IsPlayPlaylistCollectionAsyncAvailableChanged += value; remove => InnerPlaylistCollection.IsPlayPlaylistCollectionAsyncAvailableChanged -= value; } /// public virtual event EventHandler? IsPausePlaylistCollectionAsyncAvailableChanged { add => InnerPlaylistCollection.IsPausePlaylistCollectionAsyncAvailableChanged += value; remove => InnerPlaylistCollection.IsPausePlaylistCollectionAsyncAvailableChanged -= value; } /// public virtual event EventHandler? PlaylistItemsCountChanged { add => InnerPlaylistCollection.PlaylistItemsCountChanged += value; remove => InnerPlaylistCollection.PlaylistItemsCountChanged -= value; } /// public virtual bool Equals(ICorePlaylistCollectionItem other) => InnerPlaylistCollection.Equals(other); /// public virtual bool Equals(ICorePlaylistCollection other) => InnerPlaylistCollection.Equals(other); /// public virtual Task PlayPlaylistCollectionAsync(IPlaylistCollectionItem playlistItem, CancellationToken cancellationToken = default) => InnerPlaylistCollection.PlayPlaylistCollectionAsync(playlistItem, cancellationToken); /// public virtual IAsyncEnumerable GetPlaylistItemsAsync(int limit, int offset, CancellationToken cancellationToken = default) => InnerPlaylistCollection.GetPlaylistItemsAsync(limit, offset, cancellationToken); /// public virtual Task AddPlaylistItemAsync(IPlaylistCollectionItem playlistItem, int index, CancellationToken cancellationToken = default) => InnerPlaylistCollection.AddPlaylistItemAsync(playlistItem, index, cancellationToken); /// public virtual event CollectionChangedEventHandler? PlaylistItemsChanged { add => InnerPlaylistCollection.PlaylistItemsChanged += value; remove => InnerPlaylistCollection.PlaylistItemsChanged -= value; } /// public virtual Task PlayPlayableCollectionGroupAsync(CancellationToken cancellationToken = default) => Inner.PlayPlayableCollectionGroupAsync(cancellationToken); /// public virtual Task PausePlayableCollectionGroupAsync(CancellationToken cancellationToken = default) => Inner.PausePlayableCollectionGroupAsync(cancellationToken); /// public virtual int TotalChildrenCount => Inner.TotalChildrenCount; /// public virtual Task RemoveChildAsync(int index, CancellationToken cancellationToken = default) => Inner.RemoveChildAsync(index, cancellationToken); /// public virtual Task IsAddChildAvailableAsync(int index, CancellationToken cancellationToken = default) => Inner.IsAddChildAvailableAsync(index, cancellationToken); /// public virtual Task IsRemoveChildAvailableAsync(int index, CancellationToken cancellationToken = default) => Inner.IsRemoveChildAvailableAsync(index, cancellationToken); /// public virtual event EventHandler? ChildrenCountChanged { add => Inner.ChildrenCountChanged += value; remove => Inner.ChildrenCountChanged -= value; } /// public virtual bool Equals(ICorePlayableCollectionGroupChildren other) => Inner.Equals(other); /// public virtual Task PlayPlayableCollectionGroupAsync(IPlayableCollectionGroup collectionGroup, CancellationToken cancellationToken = default) => Inner.PlayPlayableCollectionGroupAsync(collectionGroup, cancellationToken); /// public virtual IAsyncEnumerable GetChildrenAsync(int limit, int offset, CancellationToken cancellationToken = default) => Inner.GetChildrenAsync(limit, offset, cancellationToken); /// public virtual Task AddChildAsync(IPlayableCollectionGroup child, int index, CancellationToken cancellationToken = default) => Inner.AddChildAsync(child, index, cancellationToken); /// public virtual event CollectionChangedEventHandler? ChildItemsChanged { add => Inner.ChildItemsChanged += value; remove => Inner.ChildItemsChanged -= value; } /// public virtual bool Equals(ICorePlayableCollectionGroup other) => Inner.Equals(other); /// public virtual ValueTask DisposeAsync() { var uniqueInstances = new HashSet() { Inner, InnerArtistCollection, InnerAlbumCollection, InnerPlaylistCollection, InnerTrackCollection, InnerDownloadable, InnerPlayable, InnerImageCollection, InnerUrlCollection, }; return new ValueTask(uniqueInstances.AsParallel() .Select(x => x.DisposeAsync().AsTask()) .Aggregate((x, y) => Task.WhenAll(x, y))); } } }