Skip to content

Commit 8cc1fed

Browse files
author
giordanol
committed
Added DependencyIbjection project
1 parent b024c6f commit 8cc1fed

File tree

5 files changed

+134
-0
lines changed

5 files changed

+134
-0
lines changed

Blumchen.sln

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "postgres", "postgres", "{8A
4343
EndProject
4444
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "demo", "demo", "{A4044484-FE08-4399-8239-14AABFA30AD7}"
4545
EndProject
46+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blumchen.DependencyInjection", "src\Blumchen.DependencyInjection\Blumchen.DependencyInjection.csproj", "{A07167E3-4CF7-40EF-8E55-A37A0F57B89D}"
47+
EndProject
4648
Global
4749
GlobalSection(SolutionConfigurationPlatforms) = preSolution
4850
Debug|Any CPU = Debug|Any CPU
@@ -69,6 +71,10 @@ Global
6971
{2BBDA071-FB1C-4D62-A954-B22EA6B1C738}.Debug|Any CPU.Build.0 = Debug|Any CPU
7072
{2BBDA071-FB1C-4D62-A954-B22EA6B1C738}.Release|Any CPU.ActiveCfg = Release|Any CPU
7173
{2BBDA071-FB1C-4D62-A954-B22EA6B1C738}.Release|Any CPU.Build.0 = Release|Any CPU
74+
{A07167E3-4CF7-40EF-8E55-A37A0F57B89D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
75+
{A07167E3-4CF7-40EF-8E55-A37A0F57B89D}.Debug|Any CPU.Build.0 = Debug|Any CPU
76+
{A07167E3-4CF7-40EF-8E55-A37A0F57B89D}.Release|Any CPU.ActiveCfg = Release|Any CPU
77+
{A07167E3-4CF7-40EF-8E55-A37A0F57B89D}.Release|Any CPU.Build.0 = Release|Any CPU
7278
EndGlobalSection
7379
GlobalSection(SolutionProperties) = preSolution
7480
HideSolutionNode = FALSE
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<VersionPrefix>0.1.0</VersionPrefix>
5+
<TargetFramework>net8.0</TargetFramework>
6+
<GenerateAssemblyTitleAttribute>true</GenerateAssemblyTitleAttribute>
7+
<GenerateAssemblyDescriptionAttribute>true</GenerateAssemblyDescriptionAttribute>
8+
<GenerateAssemblyProductAttribute>true</GenerateAssemblyProductAttribute>
9+
<GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
10+
<GenerateAssemblyVersionAttribute>true</GenerateAssemblyVersionAttribute>
11+
<GenerateAssemblyFileVersionAttribute>true</GenerateAssemblyFileVersionAttribute>
12+
<GenerateAssemblyInformationalVersionAttribute>true</GenerateAssemblyInformationalVersionAttribute>
13+
<GenerateDocumentationFile>true</GenerateDocumentationFile>
14+
<LangVersion>12.0</LangVersion>
15+
<Authors>Oskar Dudycz</Authors>
16+
<!-- <PackageIconUrl>https://github.com/event-driven-io/Blumchen/content/images/emblem.png</PackageIconUrl>-->
17+
<PackageProjectUrl>https://github.com/event-driven-io/Blumchen</PackageProjectUrl>
18+
<PackageLicenseExpression>MIT</PackageLicenseExpression>
19+
<RepositoryUrl>https://github.com/event-driven-io/Blumchen.git</RepositoryUrl>
20+
<PublishRepositoryUrl>true</PublishRepositoryUrl>
21+
<Product>Blumchen</Product>
22+
<GenerateDocumentationFile>true</GenerateDocumentationFile>
23+
<EmbedUntrackedSources>true</EmbedUntrackedSources>
24+
<IncludeSymbols>true</IncludeSymbols>
25+
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
26+
<RootNamespace>Blumchen</RootNamespace>
27+
<PublishAot>true</PublishAot>
28+
<ImplicitUsings>enable</ImplicitUsings>
29+
<Nullable>enable</Nullable>
30+
</PropertyGroup>
31+
32+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
33+
<NoWarn>1591</NoWarn>
34+
</PropertyGroup>
35+
36+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
37+
<NoWarn>1591</NoWarn>
38+
</PropertyGroup>
39+
40+
<ItemGroup>
41+
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.0" />
42+
<PackageReference Include="Polly" Version="8.4.1" />
43+
</ItemGroup>
44+
45+
<ItemGroup>
46+
<ProjectReference Include="..\Blumchen\Blumchen.csproj" />
47+
</ItemGroup>
48+
49+
</Project>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
namespace Blumchen.Configuration;
2+
public record DatabaseOptions(string ConnectionString);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using Microsoft.Extensions.DependencyInjection;
2+
#pragma warning disable IL2091
3+
4+
namespace Blumchen.Workers;
5+
6+
public static class ServiceCollectionExtensions
7+
{
8+
public static IServiceCollection AddBlumchen<T,TU>(this IServiceCollection service, T? instance = default)
9+
where T : Worker<TU> where TU : class =>
10+
instance is null
11+
? service.AddHostedService<T>()
12+
: service.AddHostedService(_=>instance);
13+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
using System.Collections.Concurrent;
2+
using System.Text.Json.Serialization;
3+
using Blumchen.Configuration;
4+
using Blumchen.Serialization;
5+
using Blumchen.Subscriptions;
6+
using Blumchen.Subscriptions.Management;
7+
using Microsoft.Extensions.Hosting;
8+
using Microsoft.Extensions.Logging;
9+
using Polly;
10+
11+
12+
namespace Blumchen.Workers;
13+
14+
public abstract class Worker<T>(
15+
DatabaseOptions databaseOptions,
16+
IHandler<T> handler,
17+
JsonSerializerContext jsonSerializerContext,
18+
IErrorProcessor errorProcessor,
19+
ResiliencePipeline pipeline,
20+
INamingPolicy namingPolicy,
21+
PublicationManagement.PublicationSetupOptions publicationSetupOptions,
22+
ReplicationSlotManagement.ReplicationSlotSetupOptions replicationSlotSetupOptions,
23+
ILoggerFactory loggerFactory): BackgroundService where T : class
24+
{
25+
private readonly ILogger<Worker<T>> _logger = loggerFactory.CreateLogger<Worker<T>>();
26+
private string WorkerName { get; } = $"{nameof(Worker<T>)}<{typeof(T).Name}>";
27+
private static readonly ConcurrentDictionary<string, Action<ILogger, string, object[]>> _actions = new(StringComparer.OrdinalIgnoreCase);
28+
private static void Notify(ILogger logger, LogLevel level, string template, params object[] parameters)
29+
{
30+
static Action<ILogger, string, object[]> LoggerAction(LogLevel ll, bool enabled) =>
31+
(ll, enabled) switch
32+
{
33+
(LogLevel.Information, true) => (logger, template, parameters) => logger.LogInformation(template, parameters),
34+
(LogLevel.Debug, true) => (logger, template, parameters) => logger.LogDebug(template, parameters),
35+
(_, _) => (_, __, ___) => { }
36+
};
37+
_actions.GetOrAdd(template,s => LoggerAction(level, logger.IsEnabled(level)))(logger, template, parameters);
38+
}
39+
40+
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
41+
{
42+
await pipeline.ExecuteAsync(async token =>
43+
{
44+
await using var subscription = new Subscription();
45+
await using var cursor = subscription.Subscribe(builder =>
46+
builder
47+
.ConnectionString(databaseOptions.ConnectionString)
48+
.WithErrorProcessor(errorProcessor)
49+
.Handles<T, IHandler<T>>(handler)
50+
.NamingPolicy(namingPolicy)
51+
.JsonContext(jsonSerializerContext)
52+
.WithPublicationOptions(publicationSetupOptions)
53+
.WithReplicationOptions(replicationSlotSetupOptions)
54+
, ct: token, loggerFactory: loggerFactory).GetAsyncEnumerator(token);
55+
Notify(_logger, LogLevel.Information,"{WorkerName} started", WorkerName);
56+
while (await cursor.MoveNextAsync().ConfigureAwait(false) && !token.IsCancellationRequested)
57+
Notify(_logger, LogLevel.Debug, "{cursor.Current} processed", cursor.Current);
58+
59+
}, stoppingToken).ConfigureAwait(false);
60+
Notify(_logger, LogLevel.Information, "{WorkerName} stopped", WorkerName);
61+
return;
62+
}
63+
64+
}

0 commit comments

Comments
 (0)