Freakout 0.0.22
See the version list below for details.
dotnet add package Freakout --version 0.0.22
NuGet\Install-Package Freakout -Version 0.0.22
<PackageReference Include="Freakout" Version="0.0.22" />
paket add Freakout --version 0.0.22
#r "nuget: Freakout, 0.0.22"
// Install Freakout as a Cake Addin
#addin nuget:?package=Freakout&version=0.0.22
// Install Freakout as a Cake Tool
#tool nuget:?package=Freakout&version=0.0.22
Freakout
📤 Just a general outbox thing
Why? Because "outbox" is closer to your chosen type of persistence (SQL Server, Postgres, etc.) than to anything else.
Which types of persistence does it support?
- Microsoft SQL Server (for when you're working with the "Microsoft.Data.SqlClient" NuGet package and
SqlConnection
/SqlTransaction
) - PostgreSQL (for when you're working with "Npgsql" NuGet package and
NpgsqlConnection
/NpgsqlTransaction
)
and that's it for now. 😅
How?
First, pull in the relevant NuGet package for your chosen type of persistence - e.g. the "Freakout.MsSql" NuGet package.
Next, enable Freakout in your app:
services.AddFreakout(new MsSqlFreakoutConfiguration(connectionString));
It will register a couple of things, e.g. a background worker that will poll the outbox for pending commands. AddFreakout
can only be called once.
Then, add your handlers:
services.AddCommandHandler<RecalculateClaimSummaryCommandHandler>();
services.AddCommandHandler<SendEmailCommandHandler>();
services.AddCommandHandler<PublishJournalEntryAddedCommandHandler>();
which will of course be resolved from the container, each in their own service scope.
Now it's fully configured - what's missing is putting something in the outbox.
Two ways of adding commands to the outbox
First way: Directly on the database transaction
Since this example is for SQL Server, and we're pretending to be working with Microsoft.Data.SqlClient
and SqlConnection
, it's natural to
provide the outbox functionality as an extension method to DbTransaction
. This way, your code can do stuff like this:
await using var connection = new SqlConnection(_connectionString);
await connection.OpenAsync();
await using var transaction = await connection.BeginTransactionAsync();
// do your own work with connection+transaction here
// (...)
// possibly call this bad boy a couple of times
await transaction.AddOutboxCommandAsync(new PublishJournalEntryAddedCommand(Id: journalEntryId));
// do more of your own work
// (...)
// commit it all atomically
await transaction.CommitAsync();
which in this case would result in publishing a couple of JournalEntryAdded
events using Rebus.
Second way: By using IOutbox
This is a neat way to do it: You can manage your unit of work with your SqlConnection
and SqlTransaction
somewhere
and then make them available to Freakout by using a FreakoutContextScope
like this:
var context = new MsSqlFreakoutContext(connection, transaction);
using (new FreakoutContextScope(context))
{
// there's an ambient context now! 🙂
}
Inside the scope, IOutbox
can be resolved, which then provides a technology-agnostic way of putting commands in the outbox!
A cool place to create/dispose FreakoutContextScope
would be in your ASP.NET Core request handler pipeline, e.g. like this:
app.Use(async (context, next) => {
var provider = context.Request.RequestServices;
// let's just assume we can get these from the request-scoped services:
var connection = provider.GetRequiredService<SqlConnection>();
var transaction = provider.GetRequiredService<SqlTransaction>();
var freakoutContext = new MsSqlFreakoutContext(connection, transaction);
using (new FreakoutContextScope(freakoutContext))
{
// there's an ambient context now! 🙂
//
// ASP.NET Core controllers can have IOutbox injected if they want!
await next();
}
});
Having IOutbox
injected is pretty neat, because it allows you to put commands in the outbox simply by going:
await outbox.AddOutboxCommandAsync(command);
without having to bother with thinking about which type of persistence is being used.
What does a command handler look like?
Outbox commands are dispatched to handlers. Handlers are classes that implement ICommandHandler<TCommand>
and are registered in the
container using the AddCommandHandler
extension method shown above.
A command handler to publish the aforementioned Rebus event could look like this (assuming Rebus has also been configured in the given container):
public class PublishJournalEntryAddedCommandHandler(IBus bus) : ICommandHandler<PublishJournalEntryAddedCommand>
{
public async Task HandleAsync(PublishJournalEntryAddedCommand command, CancellationToken token)
{
await bus.Publish(new JournalEntryAdded(command.Id));
}
}
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 is compatible. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.6.2
- microsoft.extensions.dependencyinjection (>= 3.1.0)
- microsoft.extensions.hosting (>= 3.1.0)
- nito.asyncex (>= 5.1.2)
-
.NETStandard 2.0
- Microsoft.CSharp (>= 4.7.0)
- microsoft.extensions.dependencyinjection (>= 3.1.0)
- microsoft.extensions.hosting (>= 3.1.0)
- nito.asyncex (>= 5.1.2)
- System.Reflection.Emit.Lightweight (>= 4.7.0)
-
net6.0
- microsoft.extensions.dependencyinjection (>= 3.1.0)
- microsoft.extensions.hosting (>= 3.1.0)
- nito.asyncex (>= 5.1.2)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Freakout:
Package | Downloads |
---|---|
Freakout.MsSql
Package Description |
|
Freakout.NpgSql
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
0.0.24 | 102 | 6/10/2024 |
0.0.23 | 110 | 6/10/2024 |
0.0.22 | 107 | 6/10/2024 |
0.0.21 | 160 | 4/16/2024 |
0.0.19 | 132 | 4/16/2024 |
0.0.18 | 139 | 4/15/2024 |
0.0.17 | 126 | 4/15/2024 |
0.0.16 | 133 | 4/15/2024 |
0.0.15 | 135 | 4/15/2024 |
0.0.14 | 134 | 4/15/2024 |
0.0.13 | 140 | 4/15/2024 |
0.0.12 | 131 | 4/15/2024 |
0.0.11 | 134 | 4/15/2024 |
0.0.10 | 143 | 4/15/2024 |
0.0.9 | 148 | 4/15/2024 |
0.0.8 | 135 | 4/15/2024 |
0.0.7 | 112 | 4/12/2024 |
0.0.6 | 110 | 4/12/2024 |
0.0.5 | 101 | 4/12/2024 |
0.0.4 | 111 | 4/12/2024 |
0.0.3 | 116 | 4/12/2024 |
0.0.2 | 123 | 4/4/2024 |
0.0.1 | 110 | 4/4/2024 |