-
Notifications
You must be signed in to change notification settings - Fork 169
Description
Problem
Not really a "problem", but more like a potential new feature: as emerged in #367 there may be the need to not have only one single DefaultEntryOptions, but allow users to centrally specify a custom logic that can provide different default entry options based on the cache key that it is being worked on.
Solution
Important
NOTE: nothing is confirmed yet. As of now I'm playing with the idea, but I still need to implement it and see what happens in all edge cases, etc.
The idea is to add a new option in the FusionCacheOptions class so that it's possible to specify such custom provider logic.
The initial name here #367 was "builder", but that may indicate a way to build entry options everytime, which is not necessarily true: therefore a better name feels like "provider", because it is a way to provide default entry options based on some custom logic.
The current shape is:
public class FusionCacheOptions {
// ...
public Func<EntryOptionsProviderContext, FusionCacheEntryOptions?> DefaultEntryOptionsProvider { get; set; }
}The context object contains the needed informations to implement the custom logic, and the shape is:
public class EntryOptionsProviderContext
{
public string Key { get; }
public FusionCacheEntryOptions DuplicateDefaultEntryOptions();
}Two things to consider:
- of course if the custom logic is not specified, everything remains the same as before
- the custom logic can return
null, as a way to express "in this case I'm good with the normalDefaultEntryOptions"
This means that the custom logic can:
- create a new
FusionCacheEntryOptionsfrom scratch, and return it - duplicate the
DefaultEntryOptions, apply some logic, and return it - return
null
This would allow customizations such as these:
// 1. BASIC:
// - ALWAYS CREATE A NEW ONE
DefaultEntryOptionsProvider = ctx => {
return new FusionCacheEntryOptions().SetFailSafe(...);
};
// 2. MORE COMPLEX:
// - IF KEY STARTS WITH "foo/" -> CREATE A NEW ONE
// - OTHERWISE JUST RETURN THE DEFAULT ONE
DefaultEntryOptionsProvider = ctx => {
if (ctx.Key.StartsWith("foo/")) {
// CREATE A NEW ONE
return new FusionCacheEntryOptions().SetFailSafe(...);
}
// RETURN NULL (USES THE DEFAULT ONE)
return null;
};
// 3. MOST COMPLEX:
// - IF KEY STARTS WITH "foo/" -> CREATE A NEW ONE
// - IF KEY STARTS WITH "bar/" -> DUPLICATE THE DEFAULT ONE AND CHANGE SOMETHING
// - OTHERWISE JUST RETURN NULL (USES THE DEFAULT ONE)
DefaultEntryOptionsProvider = ctx => {
if (ctx.Key.StartsWith("foo/")) {
return new FusionCacheEntryOptions().SetFailSafe(...);
}
if (ctx.Key.StartsWith("bar/")) {
return ctx.DuplicateDefaultEntryOptions().SetDuration(...);
}
return null;
};Of course the user can also reference globally defined entry options to not allocate them every time, and save resources.
For example the example 3 can be:
// SOMEWHERE ELSE
public static class MyStuff {
public static FusionCacheEntryOptions FooEntryOptions {get; set; }
public static FusionCacheEntryOptions BarEntryOptions {get; set; }
}
// ...
// 3. MOST COMPLEX:
// - IF KEY STARTS WITH "foo/" -> CREATE A NEW ONE
// - IF KEY STARTS WITH "bar/" -> DUPLICATE THE DEFAULT ONE AND CHANGE SOMETHING
// - OTHERWISE JUST RETURN NULL (USES THE DEFAULT ONE)
DefaultEntryOptionsProvider = ctx => {
if (ctx.Key.StartsWith("foo/")) {
return MyStuff.FooEntryOptions ??= new FusionCacheEntryOptions().SetFailSafe(...);
}
if (ctx.Key.StartsWith("bar/")) {
return MyStuff.BarEntryOptions ??= ctx.DuplicateDefaultEntryOptions().SetDuration(...);
}
return null;
};This should basically cover any possible need (hopefully).
Thoughts?