Skip to content

[FEATURE] 🧩 Plugins #15

@jodydonetti

Description

@jodydonetti

Scenario

While playing with the implementation of the backplane (see #11) and talking about adding metrics (see #9) the need emerged to be able to add functionalities around FusionCache via external code.

In some cases a specific interface is needed because it is a core part of the system (like the already existing IFusionCacheSerializer), but in a lot of other cases a more generic one would probably suffice.

The objective is to:

  • let other people extend FusionCache with custom needs for their projects
  • open the door to more contributions by the community for common functionalities not present in the core packages

Proposal

The idea is to create a plugin subsystem where multiple plugins can be implemented using a common interface that would allow the coordination with a FusionCache instance.

As a first draft I'm thinking about something like this:

public interface IFusionCachePlugin
{
    void Start(IFusionCache cache);
    void Stop(IFusionCache cache);
}

In the Start method a plugin implementer will receive a cache instance to then, for example, subscribe to the events they'd like (see #14) or do something else, while in the Stop they can remove the events subscriptions they've created before, to keep a system clean.

A plugin will be added to a cache with a method like IFusioCache.AddPlugin(IFusionCachePlugin plugin), similarly to the one for the distributed cache which would add the plugin instance to an internal list of plugins, and call its Start method. In the same vein, a method IFusioCache.RemovePlugin(IFusionCachePlugin plugin) can be called to remove a plugin (which in turn will call the Stop method on the plugin) for housekeeping purposes.

Dependency Injection

In a DI scenario the method will be called automatically for all the registered services implementing the IFusionCachePlugin type, like what is already happening for the IDistributedCache type here, but with potentially multiple implementations.

The code may be something like this:

[...]
var plugins = serviceProvider.GetServices<IFusionCachePlugin>();
foreach (var plugin in plugins)
{
    cache.AddPlugin(plugin);
}
[...]

Specialized plugin types

In case specific functionalities may be needed by FusionCache, a more specialized plugin type may be created simply inheriting from the base IFusionCachePlugin type and adding the specific apis needed.

If, for example, the metrics plugins need a special metrics-related method to be called for metrics-related things, we would have something like this:

public interface IFusionCacheMetricsPlugin:
    : IFusionCachePlugin
{
    Task<bool> DoMetricsStuffAsync(int param1, string param2, [etc...]);
}

NOTE: I'm still playing with the backplane impl, and it could very well fit into this as a "normal" plugin.

Other stuff to decide

Should there be a way to identify a plugin, apart from its clr type? Something like a string Id { get; set; }? It may be useful in some contexts (eg: logging).

Thoughts?

Any suggestion is more than welcome.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions