Skip to content

Commit

Permalink
WIP: Implemented caching strategies. Not yet tested.
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonmwebb-lv committed Sep 6, 2024
1 parent 54f4e70 commit 58f6326
Show file tree
Hide file tree
Showing 28 changed files with 528 additions and 420 deletions.
6 changes: 3 additions & 3 deletions Examples/Caching/Examples.Caching.MemoryCaching/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@
// Configure RCommon
services.AddRCommon()
.WithJsonSerialization<JsonNetBuilder>() // Distributed memory caching requires serialization
.WithMemoryCaching<MemoryCachingBuilder>(cache =>
.WithMemoryCaching<InMemoryCachingBuilder>(cache =>
{
cache.Configure(x =>
{
x.ExpirationScanFrequency = TimeSpan.FromMinutes(1);
})
.CacheDynamicallyCompiledExpressions();
});
cache.CacheDynamicallyCompiledExpressions();
})
.WithDistributedCaching<DistributedMemoryCacheBuilder>(cache =>
{
Expand Down
22 changes: 6 additions & 16 deletions Src/RCommon.ApplicationServices/Commands/CommandBus.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,13 @@
using System.Security.Principal;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using RCommon.ApplicationServices.Caching;
using RCommon.ApplicationServices.Commands;
using RCommon.ApplicationServices.ExecutionResults;
using RCommon.ApplicationServices.Validation;
using RCommon.Caching;
using RCommon.Reflection;

namespace RCommon.ApplicationServices.Commands
Expand All @@ -44,19 +43,19 @@ public class CommandBus : ICommandBus
{
private readonly ILogger<CommandBus> _logger;
private readonly IServiceProvider _serviceProvider;
private readonly IMemoryCache _memoryCache;
private readonly IValidationService _validationService;
private readonly IOptions<CqrsValidationOptions> _validationOptions;
private readonly ICacheService _cacheService;
private readonly CachingOptions _cachingOptions;

public CommandBus(ILogger<CommandBus> logger, IServiceProvider serviceProvider, IMemoryCache memoryCache, IValidationService validationService,
IOptions<CqrsValidationOptions> validationOptions, IOptions<CachingOptions> cachingOptions)
public CommandBus(ILogger<CommandBus> logger, IServiceProvider serviceProvider, IValidationService validationService,
IOptions<CqrsValidationOptions> validationOptions, IOptions<CachingOptions> cachingOptions, ICommonFactory<ExpressionCachingStrategy, ICacheService> cacheFactory)
{
_logger = logger;
_serviceProvider = serviceProvider;
_memoryCache = memoryCache;
_validationService = validationService;
_validationOptions = validationOptions;
_cacheService = cacheFactory.Create(ExpressionCachingStrategy.Default);
_cachingOptions = cachingOptions.Value;
}

Expand Down Expand Up @@ -135,16 +134,7 @@ private CommandExecutionDetails GetCommandExecutionDetails(Type commandType)
{
if (_cachingOptions.CachingEnabled && _cachingOptions.CacheDynamicallyCompiledExpressions)
{
var memoryCache = this._serviceProvider.GetService<IMemoryCache>();
Guard.IsNotNull(memoryCache, nameof(memoryCache));

return memoryCache.GetOrCreate(
CacheKey.With(GetType(), commandType.GetCacheKey()),
e =>
{
e.AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(1);
return this.BuildCommandDetails(commandType);
});
return _cacheService.GetOrCreate(CacheKey.With(GetType(), commandType.GetCacheKey()), this.BuildCommandDetails(commandType));
}
return this.BuildCommandDetails(commandType);
}
Expand Down
3 changes: 1 addition & 2 deletions Src/RCommon.ApplicationServices/CqrsBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using RCommon.ApplicationServices.Commands;
using RCommon.ApplicationServices.Queries;
using RCommon.EventHandling;
Expand Down
19 changes: 6 additions & 13 deletions Src/RCommon.ApplicationServices/Queries/QueryBus.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,11 @@
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using RCommon.ApplicationServices.Caching;
using RCommon.ApplicationServices.Validation;
using RCommon.Caching;
using RCommon.Reflection;

namespace RCommon.ApplicationServices.Queries
Expand All @@ -49,15 +48,17 @@ private class HandlerFuncMapping
private readonly IValidationService _validationService;
private readonly IOptions<CqrsValidationOptions> _validationOptions;
private readonly CachingOptions _cachingOptions;
private readonly ICacheService _cacheService;

public QueryBus(ILogger<QueryBus> logger, IServiceProvider serviceProvider, IValidationService validationService,
IOptions<CqrsValidationOptions> validationOptions, IOptions<CachingOptions> cachingOptions)
IOptions<CqrsValidationOptions> validationOptions, IOptions<CachingOptions> cachingOptions, ICommonFactory<ExpressionCachingStrategy, ICacheService> cacheFactory)
{
_logger = logger;
_serviceProvider = serviceProvider;
_validationService = validationService;
_validationOptions = validationOptions;
_cachingOptions = cachingOptions.Value;
_cacheService = cacheFactory.Create(ExpressionCachingStrategy.Default);
}

public async Task<TResult> DispatchQueryAsync<TResult>(IQuery<TResult> query, CancellationToken cancellationToken = default)
Expand Down Expand Up @@ -90,16 +91,8 @@ private HandlerFuncMapping GetHandlerFuncMapping(Type queryType)
{
if (_cachingOptions.CachingEnabled && _cachingOptions.CacheDynamicallyCompiledExpressions)
{
var memoryCache = this._serviceProvider.GetService<IMemoryCache>();
Guard.IsNotNull(memoryCache, nameof(memoryCache));

return memoryCache.GetOrCreate(
CacheKey.With(GetType(), queryType.GetCacheKey()),
e =>
{
e.AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(1);
return this.BuildHandlerFuncMapping(queryType);
});
return _cacheService.GetOrCreate(CacheKey.With(GetType(), queryType.GetCacheKey()),
this.BuildHandlerFuncMapping(queryType));
}
return this.BuildHandlerFuncMapping(queryType);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@
<TargetFrameworks>net6.0;net8.0;</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="8.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\RCommon.Caching\RCommon.Caching.csproj" />
<ProjectReference Include="..\RCommon.Core\RCommon.Core.csproj" />
Expand All @@ -20,5 +16,8 @@
<ItemGroup Condition=" '$(TargetFramework)' == 'net8.0' ">
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.2" />
</ItemGroup>
<ItemGroup>
<Folder Include="Caching\" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,21 @@
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

using System;
using Newtonsoft.Json;
using RCommon.Entities.ValueObjects;

namespace RCommon.ApplicationServices.Caching
namespace RCommon.Caching
{
[JsonConverter(typeof(SingleValueObjectConverter))]
public class CacheKey : SingleValueObject<string>
public class CacheKey
{
public const int MaxLength = 256;

public CacheKey(string value)
{
if (string.IsNullOrEmpty(value))
throw new ArgumentNullException(nameof(value));
if (value.Length > MaxLength)
throw new ArgumentOutOfRangeException(nameof(value), value, $"Cache keys can maximum be '{MaxLength}' in length");
}

public static CacheKey With(params string[] keys)
{
return new CacheKey(string.Join("-", keys));
Expand All @@ -41,13 +46,5 @@ public static CacheKey With(Type ownerType, params string[] keys)
{
return With($"{ownerType.GetCacheKey()}:{string.Join("-", keys)}");
}

public CacheKey(string value) : base(value)
{
if (string.IsNullOrEmpty(value))
throw new ArgumentNullException(nameof(value));
if (value.Length > MaxLength)
throw new ArgumentOutOfRangeException(nameof(value), value, $"Cache keys can maximum be '{MaxLength}' in length");
}
}
}
1 change: 1 addition & 0 deletions Src/RCommon.Caching/CachingBuilderExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using RCommon.Json;
using System;
using System.Collections.Generic;
Expand Down
13 changes: 13 additions & 0 deletions Src/RCommon.Caching/ExpressionCachingStrategy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RCommon.Caching
{
public enum ExpressionCachingStrategy
{
Default
}
}
14 changes: 14 additions & 0 deletions Src/RCommon.Caching/ICacheService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RCommon.Caching
{
public interface ICacheService
{
TData GetOrCreate<TData>(object key, TData data);
Task<TData> GetOrCreateAsync<TData>(object key, TData data);
}
}
10 changes: 5 additions & 5 deletions Src/RCommon.Core/CommonFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@

namespace RCommon
{
public class CommonFactory<T> : ICommonFactory<T>
public class CommonFactory<TResult> : ICommonFactory<TResult>
{
private readonly Func<T> _initFunc;
private readonly Func<TResult> _initFunc;

public CommonFactory(Func<T> initFunc)
public CommonFactory(Func<TResult> initFunc)
{
_initFunc = initFunc;
}

public T Create()
public TResult Create()
{
return _initFunc();
}

public T Create(Action<T> customize)
public TResult Create(Action<TResult> customize)
{
var concreteObject = _initFunc();
customize(concreteObject);
Expand Down
30 changes: 0 additions & 30 deletions Src/RCommon.Entities/ValueObjects/ISingleValueObject.cs

This file was deleted.

81 changes: 0 additions & 81 deletions Src/RCommon.Entities/ValueObjects/SingleValueObject.cs

This file was deleted.

Loading

0 comments on commit 58f6326

Please sign in to comment.