Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/keyed services #244

Merged
merged 8 commits into from
May 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions src/ZiggyCreatures.FusionCache.Chaos/ChaosMemoryCache.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using System;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using ZiggyCreatures.Caching.Fusion.Chaos.Internals;

namespace ZiggyCreatures.Caching.Fusion.Chaos;

/// <summary>
/// An implementation of <see cref="IMemoryCache"/> that acts on behalf of another one, but with a (controllable) amount of chaos in-between.
/// </summary>
public class ChaosMemoryCache
: AbstractChaosComponent
, IMemoryCache
{
private readonly IMemoryCache _innerCache;

/// <summary>
/// Initializes a new instance of the ChaosMemoryCache class.
/// </summary>
/// <param name="innerCache">The actual <see cref="IMemoryCache"/> used if and when chaos does not happen.</param>
/// <param name="logger">The logger to use, or <see langword="null"/>.</param>
public ChaosMemoryCache(IMemoryCache innerCache, ILogger<ChaosMemoryCache>? logger = null)
: base(logger)
{
_innerCache = innerCache ?? throw new ArgumentNullException(nameof(innerCache));
}

/// <inheritdoc/>
public ICacheEntry CreateEntry(object key)
{
MaybeChaos();
return _innerCache.CreateEntry(key);
}

/// <inheritdoc/>
public void Dispose()
{
// EMPTY
}

/// <inheritdoc/>
public void Remove(object key)
{
MaybeChaos();
_innerCache.Remove(key);
}

/// <inheritdoc/>
public bool TryGetValue(object key, out object? value)
{
MaybeChaos();
return _innerCache.TryGetValue(key, out value);
}
}
8 changes: 8 additions & 0 deletions src/ZiggyCreatures.FusionCache.Chaos/GlobalSuppressions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// This file is used by Code Analysis to maintain SuppressMessage
// attributes that are applied to this project.
// Project-level suppressions either have no target or are given
// a specific target and scoped to a namespace, type, member, etc.

using System.Diagnostics.CodeAnalysis;

[assembly: SuppressMessage("Style", "IDE0290:Use primary constructor")]

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

346 changes: 344 additions & 2 deletions src/ZiggyCreatures.FusionCache/FusionCacheBuilderExtMethods.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,9 @@ public static IServiceCollection AddFusionCache(this IServiceCollection services
/// </summary>
/// <param name="services">The <see cref="IServiceCollection" /> to add services to.</param>
/// <param name="cache">The custom FusionCache instance.</param>
/// <param name="asKeyedService">Also register this FusionCache instance as a keyed service.</param>
/// <returns>The <see cref="IServiceCollection"/> so that additional calls can be chained.</returns>
public static IServiceCollection AddFusionCache(this IServiceCollection services, IFusionCache cache)
public static IServiceCollection AddFusionCache(this IServiceCollection services, IFusionCache cache, bool asKeyedService)
{
if (services is null)
throw new ArgumentNullException(nameof(services));
Expand All @@ -97,9 +98,27 @@ public static IServiceCollection AddFusionCache(this IServiceCollection services
services.AddSingleton<LazyNamedCache>(new LazyNamedCache(cache.CacheName, cache));
}

if (asKeyedService)
{
services.AddKeyedSingleton<IFusionCache>(cache.CacheName, cache);
}

return services;
}

/// <summary>
/// Adds a custom instance of <see cref="IFusionCache"/> to the <see cref="IServiceCollection" />.
/// <br/><br/>
/// <strong>DOCS:</strong> <see href="https://github.com/ZiggyCreatures/FusionCache/blob/main/docs/DependencyInjection.md"/>
/// </summary>
/// <param name="services">The <see cref="IServiceCollection" /> to add services to.</param>
/// <param name="cache">The custom FusionCache instance.</param>
/// <returns>The <see cref="IServiceCollection"/> so that additional calls can be chained.</returns>
public static IServiceCollection AddFusionCache(this IServiceCollection services, IFusionCache cache)
{
return services.AddFusionCache(cache, false);
}

/// <summary>
/// Registers a named cache to the <see cref="IServiceCollection" />.
/// <br/><br/>
Expand Down Expand Up @@ -129,7 +148,7 @@ public static IFusionCacheBuilder AddFusionCache(this IServiceCollection service

services.AddFusionCacheProvider();

IFusionCacheBuilder builder = new FusionCacheBuilder(cacheName);
IFusionCacheBuilder builder = new FusionCacheBuilder(cacheName, services);

if (cacheName == FusionCacheOptions.DefaultCacheName)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ namespace ZiggyCreatures.Caching.Fusion.Internals.Builder;
internal sealed class FusionCacheBuilder
: IFusionCacheBuilder
{
public FusionCacheBuilder(string cacheName)
public FusionCacheBuilder(string cacheName, IServiceCollection services)
{
CacheName = cacheName;
Services = services;

UseRegisteredLogger = true;

Expand All @@ -36,17 +37,22 @@ public FusionCacheBuilder(string cacheName)

public string CacheName { get; }

public IServiceCollection Services { get; }

public bool UseRegisteredLogger { get; set; }
public string? LoggerKeyedServiceName { get; set; }
public ILogger<FusionCache>? Logger { get; set; }
public Func<IServiceProvider, ILogger<FusionCache>>? LoggerFactory { get; set; }
public bool ThrowIfMissingLogger { get; set; }

public bool UseRegisteredMemoryCache { get; set; }
public string? MemoryCacheKeyedServiceName { get; set; }
public IMemoryCache? MemoryCache { get; set; }
public Func<IServiceProvider, IMemoryCache>? MemoryCacheFactory { get; set; }
public bool ThrowIfMissingMemoryCache { get; set; }

public bool UseRegisteredMemoryLocker { get; set; }
public string? MemoryLockerKeyedServiceName { get; set; }
public IFusionCacheMemoryLocker? MemoryLocker { get; set; }
public Func<IServiceProvider, IFusionCacheMemoryLocker>? MemoryLockerFactory { get; set; }
public bool ThrowIfMissingMemoryLocker { get; set; }
Expand All @@ -61,22 +67,26 @@ public FusionCacheBuilder(string cacheName)
public Action<FusionCacheEntryOptions>? SetupDefaultEntryOptionsAction { get; set; }

public bool UseRegisteredSerializer { get; set; }
public string? SerializerKeyedServiceName { get; set; }
public IFusionCacheSerializer? Serializer { get; set; }
public Func<IServiceProvider, IFusionCacheSerializer>? SerializerFactory { get; set; }
public bool ThrowIfMissingSerializer { get; set; }

public bool UseRegisteredDistributedCache { get; set; }
public string? DistributedCacheKeyedServiceName { get; set; }
public bool IgnoreRegisteredMemoryDistributedCache { get; set; }
public IDistributedCache? DistributedCache { get; set; }
public Func<IServiceProvider, IDistributedCache>? DistributedCacheFactory { get; set; }
public bool ThrowIfMissingDistributedCache { get; set; }

public bool UseRegisteredBackplane { get; set; }
public string? BackplaneKeyedServiceName { get; set; }
public IFusionCacheBackplane? Backplane { get; set; }
public Func<IServiceProvider, IFusionCacheBackplane>? BackplaneFactory { get; set; }
public bool ThrowIfMissingBackplane { get; set; }

public bool UseAllRegisteredPlugins { get; set; }
public string? PluginsKeyedServiceName { get; set; }
public List<IFusionCachePlugin> Plugins { get; }
public List<Func<IServiceProvider, IFusionCachePlugin>> PluginsFactories { get; }

Expand Down Expand Up @@ -145,7 +155,14 @@ public IFusionCache Build(IServiceProvider serviceProvider)

if (UseRegisteredLogger)
{
logger = serviceProvider.GetService<ILogger<FusionCache>>();
if (string.IsNullOrWhiteSpace(LoggerKeyedServiceName))
{
logger = serviceProvider.GetService<ILogger<FusionCache>>();
}
else
{
logger = serviceProvider.GetKeyedService<ILogger<FusionCache>>(LoggerKeyedServiceName);
}
}
else if (LoggerFactory is not null)
{
Expand All @@ -166,7 +183,14 @@ public IFusionCache Build(IServiceProvider serviceProvider)

if (UseRegisteredMemoryCache)
{
memoryCache = serviceProvider.GetService<IMemoryCache>();
if (string.IsNullOrWhiteSpace(LoggerKeyedServiceName))
{
memoryCache = serviceProvider.GetService<IMemoryCache>();
}
else
{
memoryCache = serviceProvider.GetKeyedService<IMemoryCache>(MemoryCacheKeyedServiceName);
}
}
else if (MemoryCacheFactory is not null)
{
Expand All @@ -187,7 +211,14 @@ public IFusionCache Build(IServiceProvider serviceProvider)

if (UseRegisteredMemoryLocker)
{
memoryLocker = serviceProvider.GetService<IFusionCacheMemoryLocker>();
if (string.IsNullOrWhiteSpace(MemoryLockerKeyedServiceName))
{
memoryLocker = serviceProvider.GetService<IFusionCacheMemoryLocker>();
}
else
{
memoryLocker = serviceProvider.GetKeyedService<IFusionCacheMemoryLocker>(MemoryLockerKeyedServiceName);
}
}
else if (MemoryLockerFactory is not null)
{
Expand All @@ -210,7 +241,15 @@ public IFusionCache Build(IServiceProvider serviceProvider)
IDistributedCache? distributedCache;
if (UseRegisteredDistributedCache)
{
distributedCache = serviceProvider.GetService<IDistributedCache>();
if (string.IsNullOrWhiteSpace(DistributedCacheKeyedServiceName))
{
distributedCache = serviceProvider.GetService<IDistributedCache>();
}
else
{
distributedCache = serviceProvider.GetKeyedService<IDistributedCache>(DistributedCacheKeyedServiceName);
}

if (IgnoreRegisteredMemoryDistributedCache && distributedCache is MemoryDistributedCache)
{
distributedCache = null;
Expand All @@ -235,7 +274,14 @@ public IFusionCache Build(IServiceProvider serviceProvider)
IFusionCacheSerializer? serializer;
if (UseRegisteredSerializer)
{
serializer = serviceProvider.GetService<IFusionCacheSerializer>();
if (string.IsNullOrWhiteSpace(SerializerKeyedServiceName))
{
serializer = serviceProvider.GetService<IFusionCacheSerializer>();
}
else
{
serializer = serviceProvider.GetKeyedService<IFusionCacheSerializer>(SerializerKeyedServiceName);
}
}
else if (SerializerFactory is not null)
{
Expand Down Expand Up @@ -266,7 +312,14 @@ public IFusionCache Build(IServiceProvider serviceProvider)
IFusionCacheBackplane? backplane;
if (UseRegisteredBackplane)
{
backplane = serviceProvider.GetService<IFusionCacheBackplane>();
if (string.IsNullOrWhiteSpace(BackplaneKeyedServiceName))
{
backplane = serviceProvider.GetService<IFusionCacheBackplane>();
}
else
{
backplane = serviceProvider.GetKeyedService<IFusionCacheBackplane>(BackplaneKeyedServiceName);
}
}
else if (BackplaneFactory is not null)
{
Expand Down Expand Up @@ -295,6 +348,11 @@ public IFusionCache Build(IServiceProvider serviceProvider)
plugins.AddRange(serviceProvider.GetServices<IFusionCachePlugin>());
}

if (string.IsNullOrWhiteSpace(PluginsKeyedServiceName) == false)
{
plugins.AddRange(serviceProvider.GetKeyedServices<IFusionCachePlugin>(PluginsKeyedServiceName));
}

if (Plugins?.Any() == true)
{
plugins.AddRange(Plugins);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
- Perf: some minor memory/cpu optimizations
</PackageReleaseNotes>
<EnablePackageValidation>true</EnablePackageValidation>
<!--<PackageValidationBaselineVersion>0.20.0</PackageValidationBaselineVersion>-->
<PackageValidationBaselineVersion>1.0.0</PackageValidationBaselineVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
Loading
Loading