From e5f1cdcbec2acc7cca551e1b06ce71b28694c2d7 Mon Sep 17 00:00:00 2001 From: Jody Donetti Date: Sun, 18 Jul 2021 17:09:43 +0200 Subject: [PATCH] Plugins docs --- docs/PluginSample.md | 443 ++++++++++++++++++ docs/Plugins.md | 84 +++- docs/logo-plugin-128x128.png | Bin 0 -> 9997 bytes docs/logo-plugin-256x256.png | Bin 0 -> 7706 bytes docs/logo-plugin-400x400.png | Bin 0 -> 12295 bytes .../ZiggyCreatures.FusionCache.csproj | 1 + 6 files changed, 526 insertions(+), 2 deletions(-) create mode 100644 docs/PluginSample.md create mode 100644 docs/logo-plugin-128x128.png create mode 100644 docs/logo-plugin-256x256.png create mode 100644 docs/logo-plugin-400x400.png diff --git a/docs/PluginSample.md b/docs/PluginSample.md new file mode 100644 index 00000000..7bf630ea --- /dev/null +++ b/docs/PluginSample.md @@ -0,0 +1,443 @@ +
+ +![FusionCache logo](logo-plugin-128x128.png) + +
+ +# :jigsaw: A plugin sample + +Let's say we want to create a [plugin](Plugins.md) that sends an email when a fail-safe activation happens. + +For this example we will use the awesome [MailKit](https://github.com/jstedfast/MailKit) and [MimeKit](https://github.com/jstedfast/MimeKit) libraries by the great [Jeffrey Stedfast](https://github.com/jstedfast) and the free [Ethereal](https://ethereal.email/) fake smtp service. + +| 🚨 WARNING | +|:-------| +| Please keep in mind this is just an example: **don't send emails this way in real world projects!** | + + +## Getting started + +We'll start by creating the plugin itself, which would listen to **fail-safe activation** events + +```csharp +using System; +using ZiggyCreatures.Caching.Fusion.Events; + +namespace ZiggyCreatures.Caching.Fusion.Plugins.MyAwesomePlugins +{ + public class FailSafeEMailPlugin + : IFusionCachePlugin + { + + public void Start(IFusionCache cache) + { + // ADD THE HANDLER + cache.Events.FailSafeActivate += OnFailSafeActivate; + } + + public void Stop(IFusionCache cache) + { + // REMOVE THE HANDLER + cache.Events.FailSafeActivate -= OnFailSafeActivate; + } + + private void OnFailSafeActivate(object sender, FusionCacheEntryEventArgs e) + { + // DO SOMETHING HERE... + } + } +} +``` + +As you can see we register an event handler in the `Start` method and, the keep things clean, we remove it in the `Stop` method. + +Then we'll add the specific code to send emails: + +```csharp +private void OnFailSafeActivate(object sender, FusionCacheEntryEventArgs e) +{ + // PREPARE THE MAIL MESSAGE + var email = new MimeMessage(); + email.From.Add(MailboxAddress.Parse("[FROM_ADDRESS]")); + email.To.Add(MailboxAddress.Parse("[TO_ADDRESS]")); + email.Subject = "Fail-safe has been activated"; + email.Body = new TextPart(TextFormat.Plain) + { + Text = $"A fail-safe activation has occurred at {DateTimeOffset.UtcNow:O} UTC for the cache key {e.Key}" + }; + + // SEND IT + using (var smtp = new SmtpClient()) + { + smtp.Connect("smtp.ethereal.email", 587, SecureSocketOptions.StartTls); + smtp.Authenticate("[USERNAME]", "[PASSWORD]"); + smtp.Send(email); + smtp.Disconnect(true); + } +} +``` + +Anything bad that may happen in the handler itself will be automatically logged by FusionCache - of course if a logger has been registered - so there's no need to do anything extra about it. + + +## Usage + +When using DI we can then simply register it to be used in the ConfigureServices method in our classic Startup.cs file (or wherever we wire up our DI container), like this: + +```csharp +services.AddSingleton(); +``` + +and FusionCache will pick it up automatically. + +If instead we decide to go **without DI**, we simply have to do it this way: + +```csharp +var myPlugin = new FailSafeEMailPlugin(); + +var cache = new FusionCache(new FusionCacheOptions()); + +cache.AddPlugin(myPlugin); +``` + + +## Options + +All of this is fine, but it would really be better to avoid hard-coding the email **From** and **To** addresses, the **SMTP host** and so on in the source code, right? + +Being good .NET citizens, we can add some options to our plugin by following the [Options pattern](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options) as is standard practice. + +So we'll create a specific options class (that also implements the `IOptions` interface for better ease of use): + +```csharp +public class FailSafeEMailPluginOptions + : IOptions +{ + public string? FromAddress { get; set; } + public string? ToAddress { get; set; } + public string? SmtpHost { get; set; } + public int SmtpPort { get; set; } = 25; + public string? SmtpUsername { get; set; } + public string? SmtpPassword { get; set; } + + FailSafeEMailPluginOptions IOptions.Value + { + get { return this; } + } +} +``` + +Then we'll use it in our plugin: + +```csharp +public class FailSafeEMailPlugin + : IFusionCachePlugin +{ + + private FailSafeEMailPluginOptions _options; + + public FailSafeEMailPlugin(IOptions optionsAccessor) + { + // GET THE OPTIONS + _options = optionsAccessor.Value; + } + + public void Start(IFusionCache cache) + { + // ADD THE HANDLER + cache.Events.FailSafeActivate += OnFailSafeActivate; + } + + public void Stop(IFusionCache cache) + { + // REMOVE THE HANDLER + cache.Events.FailSafeActivate -= OnFailSafeActivate; + } + + private void OnFailSafeActivate(object sender, FusionCacheEntryEventArgs e) + { + // PREPARE THE MAIL MESSAGE + var email = new MimeMessage(); + email.From.Add(MailboxAddress.Parse(_options.FromAddress)); + email.To.Add(MailboxAddress.Parse(_options.ToAddress)); + email.Subject = "Fail-safe has been activated"; + email.Body = new TextPart(TextFormat.Plain) + { + Text = $"A fail-safe activation has occurred at {DateTimeOffset.UtcNow:O} UTC for the cache key {e.Key}" + }; + + // SEND IT + using (var smtp = new SmtpClient()) + { + smtp.Connect(_options.SmtpHost, _options.SmtpPort, SecureSocketOptions.StartTls); + smtp.Authenticate(_options.SmtpUsername, _options.SmtpPassword); + smtp.Send(email); + smtp.Disconnect(true); + } + } +} +``` + +Now we can imagine going on and let our users configure the plugin even more, maybe by passing a generic *mail sending service* instead of the SMTP specific one or really anything else we can think of, but I'll leave this as an exercise. + +One last thing it would be nice to have is a custom extension method for registering the plugin in the DI container, to allow for the plugin options to be configured in a strongly typed way. + +So we'll add a file like this (notice the containing namespace, per Microsoft best practices): + +```csharp +using System; +using ZiggyCreatures.Caching.Fusion; +using ZiggyCreatures.Caching.Fusion.Plugins; +using ZiggyCreatures.Caching.Fusion.Plugins.MyAwesomePlugins; + +namespace Microsoft.Extensions.DependencyInjection +{ + public static class FailSafeEMailPluginServiceCollectionExtensions + { + public static IServiceCollection AddFusionCacheFailSafeEMailPlugin(this IServiceCollection services, Action? setupOptionsAction = null) + { + if (services is null) + throw new ArgumentNullException(nameof(services)); + + // ENSURE THE OPTIONS SYSTEM IS AVAILABLE + services.AddOptions(); + + // OPTIONAL CUSTOM CONFIGURATION OF OPTIONS + if (setupOptionsAction is object) + services.Configure(setupOptionsAction); + + //REGISTER THE SERVICE + services.AddSingleton(); + + return services; + } + } +} +``` + +By doing this we are allowing our users to have a nice, strongly typed way of registering and configuring our plugin, like this: + +```csharp +services.AddFusionCacheFailSafeEMailPlugin(options => +{ + options.FromAddress = "sender@example.org"; + options.ToAddress = "target@example.org"; + options.SmtpHost = "smtp.ethereal.email"; + options.SmtpPort = 587; + options.SmtpUsername = "[USERNAME]"; + options.SmtpPassword = "[PASSWORD]"; +}); +``` + +Of course all of this can still be done even **without DI** at all: + +```csharp +var myPlugin = new FailSafeEMailPlugin(new FailSafeEMailPluginOptions() +{ + FromAddress = "sender@example.org", + ToAddress = "target@example.org", + SmtpHost = "smtp.ethereal.email", + SmtpPort = 587, + SmtpUsername = "[USERNAME]", + SmtpPassword = "[PASSWORD]" +}); + +var cache = new FusionCache(new FusionCacheOptions()); + +cache.AddPlugin(myPlugin); +``` + +## End result + +This is what the finished plugin would look like, splitted in 3 different files. + +File `FailSafeEMailPluginOptions.cs`: + +```csharp +using System; +using Microsoft.Extensions.Options; + +namespace ZiggyCreatures.Caching.Fusion.Plugins.MyAwesomePlugins +{ + public class FailSafeEMailPluginOptions + : IOptions + { + public string? FromAddress { get; set; } + public string? ToAddress { get; set; } + public string? SmtpHost { get; set; } + public int SmtpPort { get; set; } = 25; + public string? SmtpUsername { get; set; } + public string? SmtpPassword { get; set; } + + FailSafeEMailPluginOptions IOptions.Value + { + get { return this; } + } + } +} +``` + +File `FailSafeEMailPlugin.cs`: + +```csharp +using System; +using MailKit.Net.Smtp; +using MailKit.Security; +using Microsoft.Extensions.Options; +using MimeKit; +using MimeKit.Text; +using ZiggyCreatures.Caching.Fusion.Events; + +namespace ZiggyCreatures.Caching.Fusion.Plugins.MyAwesomePlugins +{ + public class FailSafeEMailPlugin + : IFusionCachePlugin + { + + private FailSafeEMailPluginOptions _options; + + public FailSafeEMailPlugin(IOptions optionsAccessor) + { + // GET THE OPTIONS + _options = optionsAccessor.Value; + } + + public void Start(IFusionCache cache) + { + // ADD THE HANDLER + cache.Events.FailSafeActivate += OnFailSafeActivate; + } + + public void Stop(IFusionCache cache) + { + // REMOVE THE HANDLER + cache.Events.FailSafeActivate -= OnFailSafeActivate; + } + + private void OnFailSafeActivate(object sender, FusionCacheEntryEventArgs e) + { + // PREPARE THE MAIL MESSAGE + var email = new MimeMessage(); + email.From.Add(MailboxAddress.Parse(_options.FromAddress)); + email.To.Add(MailboxAddress.Parse(_options.ToAddress)); + email.Subject = "Fail-safe has been activated"; + email.Body = new TextPart(TextFormat.Plain) + { + Text = $"A fail-safe activation has occurred at {DateTimeOffset.UtcNow:O} UTC for the cache key {e.Key}" + }; + + // SEND IT + using (var smtp = new SmtpClient()) + { + smtp.Connect(_options.SmtpHost, _options.SmtpPort, SecureSocketOptions.StartTls); + smtp.Authenticate(_options.SmtpUsername, _options.SmtpPassword); + smtp.Send(email); + smtp.Disconnect(true); + } + } + } +} +``` + +File `FailSafeEMailPluginServiceCollectionExtensions.cs`: + +```csharp +using System; +using ZiggyCreatures.Caching.Fusion; +using ZiggyCreatures.Caching.Fusion.Plugins; +using ZiggyCreatures.Caching.Fusion.Plugins.MyAwesomePlugins; + +namespace Microsoft.Extensions.DependencyInjection +{ + public static class FailSafeEMailPluginServiceCollectionExtensions + { + public static IServiceCollection AddFusionCacheFailSafeEMailPlugin(this IServiceCollection services, Action? setupOptionsAction = null) + { + if (services is null) + throw new ArgumentNullException(nameof(services)); + + // ENSURE THE OPTIONS SYSTEM IS AVAILABLE + services.AddOptions(); + + // OPTIONAL CUSTOM CONFIGURATION OF OPTIONS + if (setupOptionsAction is object) + services.Configure(setupOptionsAction); + + //REGISTER THE SERVICE + services.AddSingleton(); + + return services; + } + } +} +``` + +
+
+
+
+ +## 💅 Final polishing + +Just a couple of suggestions here. + + +### Name + +Choose a name that clearly explain what the plugin does: I know, naming things is hard, but take your time. + + +### Namespace + +You can of course use the namespace you prefer, but if you want to be in the common FusionCache namespace I'd suggest going with something like `ZiggyCreatures.Caching.Fusion.Plugins.BrandOrCompanyOrFeatureSubject.MyPlugin` to keep everything in place and make it such that other any potential plugin will not collide with others. Some examples + + +### Xml Comments + +It would be nice for users of our plugin to know what they are doing **while** they are doing it. By using [xml comments](https://docs.microsoft.com/en-us/dotnet/csharp/codedoc) you can ensure a nice learning path so that each property, method or option available is clearly documented and they will learn while doing it. + + +### Documentation + +If the features available are a lot and/or complicated, it would useful for users to have some help pages to go to for a deeper learning on top of code comments. + +A couple of simple markdown pages hosted directly on the GitHub repo page or wherever you want would do the trick. + + +### Package Name + +Nuget package naming works via prefix so, for example, official Microsoft stuff is named `Microsoft.*` and it is possible to "lock" prefixes via a reservation process: because of this, the `ZiggyCreatures.*` prefix in Nuget is reserved and will be used for other ZiggyCreatures projects in the future. + +One thing you can do if you want to be found on Nuget when searching for FusionCache packages would be to put `ZiggyCreatures.FusionCache` in the name. + +An example may be something like: + +- `JaneDoe.ZiggyCreatures.FusionCache.Plugins.Metrics.OpenTelemetryPlugin` +- `JonDoe.ZiggyCreatures.FusionCache.Plugins.Notifications.MyNotificationsPlugin` + +Obviously the package - if you want to create one - in the end is all yours so these are just suggestions. + +Oh, and if you come up with a better way please [**:envelope: drop me a line**](https://twitter.com/jodydonetti)! + + +### Package Logo + +Of course use your own logo if you like, it goes without saying! + +Please **⚠ DON'T USE** the official FusionCache logo as-is for your own third-party plugin or other packages: the reasoning is I'd like for users to differentiate between **official packages** and **third party** packages. + +A lot of times though it's not easy to create or came up with a nice logo, and the default one in Nuget would not make your package emerge. + +So, to keep a common branding and make FusionCache plugins recognizable I've created a slightly different logo, available in different sizes: + +**128x128:** + +![FusionCache logo - 400x400](logo-plugin-128x128.png) + +**256x256:** + +![FusionCache logo - 400x400](logo-plugin-256x256.png) + +**400x400:** + +![FusionCache logo - 400x400](logo-plugin-400x400.png) diff --git a/docs/Plugins.md b/docs/Plugins.md index 7909c33b..f393b928 100644 --- a/docs/Plugins.md +++ b/docs/Plugins.md @@ -1,9 +1,89 @@
-![FusionCache logo](logo-128x128.png) +![FusionCache logo](logo-plugin-128x128.png)
# :jigsaw: Plugins -Coming soon \ No newline at end of file +FusionCache supports extensibility via plugins: it is possible for example to listen to [events](Events.md) and react in any way you want. + +In time, the most useful plugins will be listed directly in the homepage. + + +## How to create a plugin + +Simply write a class that implements the [`IFusionCachePlugin`](https://github.com/jodydonetti/ZiggyCreatures.FusionCache/blob/main/src/ZiggyCreatures.FusionCache/Plugins/IFusionCachePlugin.cs) interface, which basically boils down to implement just the `Start` and `Stop` methods: from there you can setup your custom logic and do your thing. + +Of course it can also accept its own set of options, typically modelled via `IOptions` and friends. + +If you like there's a [:jigsaw: complete sample](PluginSample.md) available. + + +## How to use a plugin via DI + +Register your plugin type in the DI container (better before registering FusionCache itself) to respond to the `IFusionCachePlugin` service as a singleton: when a FusionCache instance will be requested, all plugin types registered will be auto-discovered, added (and started) automatically. + +Of course you can also define your own custom ext method to be a better .NET citizen (see the full example below). + +**Example:** + +```csharp +[...] +services.AddSingleton(); +services.AddFusionCache(); +[...] +``` + +or with your own custom ext method + custom options: + +```csharp +[...] +services.AddMyFusionCachePlugin(options => { + options.Whatever = 42; +}); +services.AddFusionCache(); +[...] +``` + +Of course you can register multiple plugins, all responding to the same `IFusionCachePlugin` service, and they will all be picked up by FusionCache when needed. + +**Example:** + +```csharp +[...] +services.AddSingleton(); +services.AddSingleton(); +services.AddFusionCache(); +[...] +``` + + +## How to use a plugin without DI +Just create an instance of your plugin and pass it to the `cache.AddPlugin` method. + +**Example:** + +```csharp +var firstPlugin = new MyFirstPlugin(); +var secondPlugin = new MySecondPlugin(); + +var cache = new FusionCache(new FusionCacheOptions()); + +cache.AddPlugin(firstPlugin); +cache.AddPlugin(secondPlugin); +``` + +:warning: Remember that, in case the `Start` method of your plugin throws and exception, an `InvalidOperationException` would also be thrown by the `AddPlugin` method itself (with the original exception as the inner one), whereas in the DI way this is already taken care of and no unhandled exception will be thrown. In both cases the original exception will be logged. + + +## How to remove a plugin + +Normally there's no need to remove a plugin manually: if you just want to clean things up "at the end" (and you should do it) you don't have to do anything because when a `FusionCache` instance is disposed, all added plugins will be automatically stopped and removed. + +If though, for whatever reason, you need to keep using a FusionCache instance after removing a particular plugin you've previously added, you can call the `cache.RemovePlugin` method: it will automatically call the `Stop` method of the plugin and then remove it. + + +## A practical example + +Want to follow a complete, end-to-end example to create your first plugin? There's one available [:jigsaw: right here](PluginSample.md). \ No newline at end of file diff --git a/docs/logo-plugin-128x128.png b/docs/logo-plugin-128x128.png new file mode 100644 index 0000000000000000000000000000000000000000..9184a30fc5b92ea7a2b349aab39859373b9fd578 GIT binary patch literal 9997 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 t1?y(7XpY5>t*F?PfwNeFQ^ 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 literal 0 HcmV?d00001 diff --git a/src/ZiggyCreatures.FusionCache/ZiggyCreatures.FusionCache.csproj b/src/ZiggyCreatures.FusionCache/ZiggyCreatures.FusionCache.csproj index 7022960e..22c035b2 100644 --- a/src/ZiggyCreatures.FusionCache/ZiggyCreatures.FusionCache.csproj +++ b/src/ZiggyCreatures.FusionCache/ZiggyCreatures.FusionCache.csproj @@ -30,6 +30,7 @@ +