diff --git a/src/XperienceCommunity.DataRepository/DependencyInjection.cs b/src/XperienceCommunity.DataRepository/DependencyInjection.cs index ceeedf4..d255e5f 100644 --- a/src/XperienceCommunity.DataRepository/DependencyInjection.cs +++ b/src/XperienceCommunity.DataRepository/DependencyInjection.cs @@ -33,6 +33,8 @@ public static IServiceCollection AddXperienceDataRepositories(this IServiceColle services.TryAddScoped(typeof(IPageRepository<>), typeof(PageTypeRepository<>)); + services.TryAddScoped(); + return services; } } diff --git a/src/XperienceCommunity.DataRepository/Interfaces/IMediaFileRepository.cs b/src/XperienceCommunity.DataRepository/Interfaces/IMediaFileRepository.cs new file mode 100644 index 0000000..fb2533f --- /dev/null +++ b/src/XperienceCommunity.DataRepository/Interfaces/IMediaFileRepository.cs @@ -0,0 +1,29 @@ +using System.Collections.Immutable; + +using CMS.MediaLibrary; + +namespace XperienceCommunity.DataRepository.Interfaces; + +/// +/// Interface for media file repository to handle media file operations. +/// +public interface IMediaFileRepository +{ + /// + /// Retrieves a list of media files based on the provided GUIDs. + /// + /// The GUIDs of the media files to retrieve. + /// A token to monitor for cancellation requests. + /// A task that represents the asynchronous operation. The task result contains an immutable list of . + Task> GetMediaFilesAsync(IEnumerable mediaFileGuids, + CancellationToken cancellationToken = default); + + /// + /// Retrieves a list of media files based on the provided related items. + /// + /// The related items to retrieve media files from. + /// A token to monitor for cancellation requests. + /// A task that represents the asynchronous operation. The task result contains an immutable list of . + Task> GetAssetsFromRelatedItemsAsync(IEnumerable items, + CancellationToken cancellationToken = default); +} diff --git a/src/XperienceCommunity.DataRepository/MediaFileRepository.cs b/src/XperienceCommunity.DataRepository/MediaFileRepository.cs new file mode 100644 index 0000000..aeaac5b --- /dev/null +++ b/src/XperienceCommunity.DataRepository/MediaFileRepository.cs @@ -0,0 +1,100 @@ +using System.Collections.Immutable; + +using CMS.DataEngine; +using CMS.Helpers; +using CMS.MediaLibrary; + +using XperienceCommunity.DataRepository.Interfaces; +using XperienceCommunity.DataRepository.Models; + +namespace XperienceCommunity.DataRepository; + +public sealed class MediaFileRepository : IMediaFileRepository +{ + private readonly IProgressiveCache cache; + private readonly int cacheMinutes; + + public MediaFileRepository(IProgressiveCache cache, RepositoryOptions options) + { + this.cache = cache; + cacheMinutes = options?.CacheMinutes ?? 10; + } + + public async Task> GetAssetsFromRelatedItemsAsync(IEnumerable items, + CancellationToken cancellationToken = default) + { + var assetItems = items?.ToList() ?? []; + + if (assetItems.Count == 0) + { + return []; + } + + return await cache.LoadAsync( + async (cacheSettings, ct) => + { + var results = (await new ObjectQuery() + .ForAssets(assetItems) + .GetEnumerableTypedResultAsync(cancellationToken: ct)) + .ToList() ?? []; + + string[] dependencyKeys = results + .Select(result => $"mediafile|{result.FileGUID}") + .ToArray(); + + cacheSettings.CacheDependency = CacheHelper.GetCacheDependency(dependencyKeys); + + return results.ToImmutableList(); + }, + new CacheSettings( + cacheMinutes: cacheMinutes, + useSlidingExpiration: true, + cacheItemNameParts: + [ + nameof(MediaFileRepository), + nameof(GetAssetsFromRelatedItemsAsync), + .. assetItems.OrderBy(item => item.Name).Select(item => item.Name) ?? [], + ] + ), cancellationToken + ); + } + + public async Task> GetMediaFilesAsync(IEnumerable mediaFileGuids, + CancellationToken cancellationToken = default) + { + var guidList = mediaFileGuids?.ToList() ?? []; + + if (guidList.Count == 0) + { + return []; + } + + return await cache.LoadAsync( + async (cacheSettings, ct) => + { + var results = (await new ObjectQuery() + .WhereIn(nameof(MediaFileInfo.FileGUID), guidList) + .GetEnumerableTypedResultAsync(cancellationToken: ct)) + ?.ToList() ?? []; + + string[] dependencyKeys = guidList + .Select(x => $"mediafile|{x}") + .ToArray(); + + cacheSettings.CacheDependency = CacheHelper.GetCacheDependency(dependencyKeys); + + return results.ToImmutableList(); + }, + new CacheSettings( + cacheMinutes: cacheMinutes, + useSlidingExpiration: true, + cacheItemNameParts: + [ + nameof(MediaFileRepository), + nameof(GetMediaFilesAsync), + guidList.GetHashCode(), + ] + ), cancellationToken + ); + } +}