diff --git a/zero.Core/Collections/CachableEntityCollection.cs b/zero.Core/Collections/CachableEntityCollection.cs new file mode 100644 index 00000000..74f00932 --- /dev/null +++ b/zero.Core/Collections/CachableEntityCollection.cs @@ -0,0 +1,37 @@ +namespace zero.Collections; + +public record CachableEntityCollectionOptions(bool CacheIndividual, bool CacheAll); + + +public abstract class CachableEntityCollection : EntityCollection where T : ZeroIdEntity, new() +{ + protected CachableEntityCollectionOptions CacheOptions { get; set; } + + protected ICollectionCache Cache { get; set; } + + + public CachableEntityCollection(ICollectionContext collectionContext, ICollectionCache collectionCache) : base(collectionContext) + { + CacheOptions = new(CacheIndividual: true, CacheAll: false); // TODO when props update we need to update Cache.For() + Cache = collectionCache.For(CacheOptions); + } + + + /// + public override async Task Load(string id, string changeVector = null) + { + if (changeVector.IsNullOrEmpty() && Cache.TryGetValue(id, out T model)) + { + return model; + } + + return await base.Load(id, changeVector); + } + + + /// + public override Task> Load(IEnumerable ids) + { + return base.Load(ids); + } +} \ No newline at end of file diff --git a/zero.Core/Collections/CollectionCache.cs b/zero.Core/Collections/CollectionCache.cs new file mode 100644 index 00000000..8549e144 --- /dev/null +++ b/zero.Core/Collections/CollectionCache.cs @@ -0,0 +1,39 @@ +using System.Collections.Concurrent; + +namespace zero.Collections; + +public class CollectionCache : ICollectionCache +{ + protected ConcurrentDictionary _cache = new(); + + + public CollectionCache() + { + + } + + public bool TryGetValue(string id, out T model) + { + if (_cache.TryGetValue(id, out object modelObj)) + { + model = (T)modelObj; + return true; + } + + model = default; + return false; + } + + public ICollectionCache For(CachableEntityCollectionOptions options) + { + return this; + } +} + + +public interface ICollectionCache +{ + ICollectionCache For(CachableEntityCollectionOptions options); + + bool TryGetValue(string id, out T model); +} \ No newline at end of file diff --git a/zero.Core/Collections/CountriesCollection.cs b/zero.Core/Collections/CountriesCollection.cs index 7592297f..62b2aa80 100644 --- a/zero.Core/Collections/CountriesCollection.cs +++ b/zero.Core/Collections/CountriesCollection.cs @@ -2,9 +2,9 @@ namespace zero.Collections; -public class CountriesCollection : EntityCollection, ICountriesCollection +public class CountriesCollection : CachableEntityCollection, ICountriesCollection { - public CountriesCollection(ICollectionContext context) : base(context) { } + public CountriesCollection(ICollectionContext context, ICollectionCache cache) : base(context, cache) { } /// protected override void ValidationRules(ZeroValidator validator) diff --git a/zero.Core/Collections/EntityCollection.cs b/zero.Core/Collections/EntityCollection.cs index cf407e3e..9b1f1f4b 100644 --- a/zero.Core/Collections/EntityCollection.cs +++ b/zero.Core/Collections/EntityCollection.cs @@ -4,7 +4,7 @@ using Raven.Client.Documents.Linq; namespace zero.Collections; -public abstract partial class EntityCollection : IEntityCollection where T : ZeroIdEntity, new() +public abstract class EntityCollection : IEntityCollection where T : ZeroIdEntity, new() { /// public Guid Guid { get; private set; } = Guid.NewGuid(); @@ -29,7 +29,7 @@ public abstract partial class EntityCollection : IEntityCollection where T Operations = collectionContext.Operations; Context = collectionContext.Context; Interceptors = collectionContext.Interceptors; - Options = new(true); + Options = new(IncludeInactive: true); }