Skip to content

Commit a63ae71

Browse files
committed
refactor: convert remaining extensions to C# 14 extension members
- refactor: migrate all classic `this`-parameter extension methods to `extension(...)` member blocks for consistency with the new convention - refactor(abstractions): convert container/service/event-listener registration extensions - refactor(core): convert string, env, directories, and log-level extensions - refactor(services-core): convert log rolling-interval extension - refactor(caching/messaging/mail/storage/search/database/telemetry/templating/persistence/workers/network/scripting): convert DI registration and helper extensions, keeping non-extension static helpers (ParseOptions, CreateClient, Provider<T>) outside the blocks - refactor: use generic-receiver `extension<T>(...)` form for IQueryable and IReadOnlyList extensions
1 parent 6b911e9 commit a63ae71

31 files changed

Lines changed: 768 additions & 688 deletions

File tree

src/SquidStd.Abstractions/Extensions/Container/AddTypedListMethodExtension.cs

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,31 @@ namespace SquidStd.Abstractions.Extensions.Container;
77
/// </summary>
88
public static class AddTypedListMethodExtension
99
{
10-
/// <summary>
11-
/// Adds an entity to a typed list in the DryIoc container.
12-
/// If the list doesn't exist, it creates and registers a new one.
13-
/// </summary>
14-
/// <typeparam name="TListEntity">The type of entities in the list.</typeparam>
1510
/// <param name="container">The DryIoc container.</param>
16-
/// <param name="entity">The entity to add to the list.</param>
17-
/// <returns>The same container for chaining.</returns>
18-
public static IContainer AddToRegisterTypedList<TListEntity>(this IContainer container, TListEntity entity)
11+
extension(IContainer container)
1912
{
20-
// Try resolve existing list
21-
if (container.IsRegistered<List<TListEntity>>())
13+
/// <summary>
14+
/// Adds an entity to a typed list in the DryIoc container.
15+
/// If the list doesn't exist, it creates and registers a new one.
16+
/// </summary>
17+
/// <typeparam name="TListEntity">The type of entities in the list.</typeparam>
18+
/// <param name="entity">The entity to add to the list.</param>
19+
/// <returns>The same container for chaining.</returns>
20+
public IContainer AddToRegisterTypedList<TListEntity>(TListEntity entity)
2221
{
23-
var typedList = container.Resolve<List<TListEntity>>();
24-
typedList.Add(entity);
25-
}
26-
else
27-
{
28-
var typedList = new List<TListEntity> { entity };
29-
container.RegisterInstance(typedList);
30-
}
22+
// Try resolve existing list
23+
if (container.IsRegistered<List<TListEntity>>())
24+
{
25+
var typedList = container.Resolve<List<TListEntity>>();
26+
typedList.Add(entity);
27+
}
28+
else
29+
{
30+
var typedList = new List<TListEntity> { entity };
31+
container.RegisterInstance(typedList);
32+
}
3133

32-
return container;
34+
return container;
35+
}
3336
}
3437
}

src/SquidStd.Abstractions/Extensions/Events/RegisterEventListenerExtension.cs

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,28 @@ namespace SquidStd.Abstractions.Extensions.Events;
1010
/// </summary>
1111
public static class RegisterEventListenerExtension
1212
{
13-
/// <summary>
14-
/// Registers a listener implementation as a singleton and records it for auto-subscription.
15-
/// </summary>
16-
/// <typeparam name="TEvent">The event type the listener handles.</typeparam>
17-
/// <typeparam name="TListener">The listener implementation type.</typeparam>
1813
/// <param name="container">The DryIoc container.</param>
19-
/// <returns>The same container for chaining.</returns>
20-
public static IContainer RegisterEventListener<TEvent, TListener>(this IContainer container)
21-
where TEvent : IEvent
22-
where TListener : class, IEventListener<TEvent>
14+
extension(IContainer container)
2315
{
24-
container.Register<TListener>(Reuse.Singleton);
25-
container.AddToRegisterTypedList(
26-
new EventListenerRegistration(
27-
typeof(TListener),
28-
(bus, resolver) => bus.RegisterListener(resolver.Resolve<TListener>())
29-
)
30-
);
16+
/// <summary>
17+
/// Registers a listener implementation as a singleton and records it for auto-subscription.
18+
/// </summary>
19+
/// <typeparam name="TEvent">The event type the listener handles.</typeparam>
20+
/// <typeparam name="TListener">The listener implementation type.</typeparam>
21+
/// <returns>The same container for chaining.</returns>
22+
public IContainer RegisterEventListener<TEvent, TListener>()
23+
where TEvent : IEvent
24+
where TListener : class, IEventListener<TEvent>
25+
{
26+
container.Register<TListener>(Reuse.Singleton);
27+
container.AddToRegisterTypedList(
28+
new EventListenerRegistration(
29+
typeof(TListener),
30+
(bus, resolver) => bus.RegisterListener(resolver.Resolve<TListener>())
31+
)
32+
);
3133

32-
return container;
34+
return container;
35+
}
3336
}
3437
}

src/SquidStd.Abstractions/Extensions/Services/RegisterStdServiceExtension.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,17 @@ namespace SquidStd.Abstractions.Extensions.Services;
66

77
public static class RegisterStdServiceExtension
88
{
9-
public static IContainer RegisterStdService<TService, TImplementation>(this IContainer container, int priority = 0)
10-
where TService : class
11-
where TImplementation : class, TService
9+
extension(IContainer container)
1210
{
13-
container.Register<TService, TImplementation>(Reuse.Singleton);
11+
public IContainer RegisterStdService<TService, TImplementation>(int priority = 0)
12+
where TService : class
13+
where TImplementation : class, TService
14+
{
15+
container.Register<TService, TImplementation>(Reuse.Singleton);
1416

15-
container.AddToRegisterTypedList(new ServiceRegistrationData(typeof(TService), typeof(TImplementation), priority));
17+
container.AddToRegisterTypedList(new ServiceRegistrationData(typeof(TService), typeof(TImplementation), priority));
1618

17-
return container;
19+
return container;
20+
}
1821
}
1922
}

src/SquidStd.Caching.Redis/Extensions/RedisCacheRegistrationExtensions.cs

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -15,52 +15,54 @@ namespace SquidStd.Caching.Redis.Extensions;
1515
/// </summary>
1616
public static class RedisCacheRegistrationExtensions
1717
{
18-
/// <summary>Registers the Redis cache from explicit options.</summary>
19-
public static IContainer AddRedisCache(
20-
this IContainer container,
21-
RedisCacheOptions options,
22-
CacheOptions? cacheOptions = null
23-
)
18+
extension(IContainer container)
2419
{
25-
ArgumentNullException.ThrowIfNull(container);
26-
ArgumentNullException.ThrowIfNull(options);
20+
/// <summary>Registers the Redis cache from explicit options.</summary>
21+
public IContainer AddRedisCache(
22+
RedisCacheOptions options,
23+
CacheOptions? cacheOptions = null
24+
)
25+
{
26+
ArgumentNullException.ThrowIfNull(container);
27+
ArgumentNullException.ThrowIfNull(options);
2728

28-
container.RegisterInstance(cacheOptions ?? new CacheOptions());
29-
container.RegisterInstance(options);
29+
container.RegisterInstance(cacheOptions ?? new CacheOptions());
30+
container.RegisterInstance(options);
3031

31-
var serializer = new JsonDataSerializer();
32-
container.RegisterInstance<IDataSerializer>(serializer, IfAlreadyRegistered.Keep);
33-
container.RegisterInstance<IDataDeserializer>(serializer, IfAlreadyRegistered.Keep);
32+
var serializer = new JsonDataSerializer();
33+
container.RegisterInstance<IDataSerializer>(serializer, IfAlreadyRegistered.Keep);
34+
container.RegisterInstance<IDataDeserializer>(serializer, IfAlreadyRegistered.Keep);
3435

35-
var metrics = new CacheMetricsProvider();
36-
container.RegisterInstance<ICacheMetrics>(metrics);
37-
container.RegisterInstance<IMetricProvider>(metrics);
36+
var metrics = new CacheMetricsProvider();
37+
container.RegisterInstance<ICacheMetrics>(metrics);
38+
container.RegisterInstance<IMetricProvider>(metrics);
3839

39-
container.Register<ICacheProvider, RedisCacheProvider>(Reuse.Singleton);
40-
container.Register<ICacheService, CacheService>(Reuse.Singleton);
40+
container.Register<ICacheProvider, RedisCacheProvider>(Reuse.Singleton);
41+
container.Register<ICacheService, CacheService>(Reuse.Singleton);
4142

42-
return container;
43-
}
43+
return container;
44+
}
4445

45-
/// <summary>Registers the Redis cache from a connection string (scheme must be "redis").</summary>
46-
public static IContainer AddRedisCache(this IContainer container, string connectionString)
47-
{
48-
ArgumentNullException.ThrowIfNull(container);
46+
/// <summary>Registers the Redis cache from a connection string (scheme must be "redis").</summary>
47+
public IContainer AddRedisCache(string connectionString)
48+
{
49+
ArgumentNullException.ThrowIfNull(container);
4950

50-
var cs = CacheConnectionString.Parse(connectionString);
51+
var cs = CacheConnectionString.Parse(connectionString);
5152

52-
if (!string.Equals(cs.Scheme, "redis", StringComparison.OrdinalIgnoreCase))
53-
{
54-
throw new ArgumentException(
55-
$"Expected a 'redis://' connection string but got '{cs.Scheme}://'.",
56-
nameof(connectionString)
57-
);
58-
}
53+
if (!string.Equals(cs.Scheme, "redis", StringComparison.OrdinalIgnoreCase))
54+
{
55+
throw new ArgumentException(
56+
$"Expected a 'redis://' connection string but got '{cs.Scheme}://'.",
57+
nameof(connectionString)
58+
);
59+
}
5960

60-
var host = string.IsNullOrEmpty(cs.Host) ? "localhost" : cs.Host;
61-
var port = cs.Port ?? 6379;
62-
var options = new RedisCacheOptions { Configuration = $"{host}:{port}" };
61+
var host = string.IsNullOrEmpty(cs.Host) ? "localhost" : cs.Host;
62+
var port = cs.Port ?? 6379;
63+
var options = new RedisCacheOptions { Configuration = $"{host}:{port}" };
6364

64-
return container.AddRedisCache(options, cs.ToCacheOptions());
65+
return container.AddRedisCache(options, cs.ToCacheOptions());
66+
}
6567
}
6668
}

src/SquidStd.Caching/Extensions/CacheRegistrationExtensions.cs

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,44 +15,47 @@ namespace SquidStd.Caching.Extensions;
1515
/// </summary>
1616
public static class CacheRegistrationExtensions
1717
{
18-
/// <summary>Registers the in-memory cache (provider, facade, metrics, serializer).</summary>
19-
public static IContainer AddInMemoryCache(this IContainer container, CacheOptions? options = null)
18+
extension(IContainer container)
2019
{
21-
ArgumentNullException.ThrowIfNull(container);
20+
/// <summary>Registers the in-memory cache (provider, facade, metrics, serializer).</summary>
21+
public IContainer AddInMemoryCache(CacheOptions? options = null)
22+
{
23+
ArgumentNullException.ThrowIfNull(container);
2224

23-
container.RegisterInstance(options ?? new CacheOptions());
25+
container.RegisterInstance(options ?? new CacheOptions());
2426

25-
var serializer = new JsonDataSerializer();
26-
container.RegisterInstance<IDataSerializer>(serializer, IfAlreadyRegistered.Keep);
27-
container.RegisterInstance<IDataDeserializer>(serializer, IfAlreadyRegistered.Keep);
27+
var serializer = new JsonDataSerializer();
28+
container.RegisterInstance<IDataSerializer>(serializer, IfAlreadyRegistered.Keep);
29+
container.RegisterInstance<IDataDeserializer>(serializer, IfAlreadyRegistered.Keep);
2830

29-
container.RegisterInstance<IMemoryCache>(new MemoryCache(new MemoryCacheOptions()), IfAlreadyRegistered.Keep);
31+
container.RegisterInstance<IMemoryCache>(new MemoryCache(new MemoryCacheOptions()), IfAlreadyRegistered.Keep);
3032

31-
var metrics = new CacheMetricsProvider();
32-
container.RegisterInstance<ICacheMetrics>(metrics);
33-
container.RegisterInstance<IMetricProvider>(metrics);
33+
var metrics = new CacheMetricsProvider();
34+
container.RegisterInstance<ICacheMetrics>(metrics);
35+
container.RegisterInstance<IMetricProvider>(metrics);
3436

35-
container.Register<ICacheProvider, InMemoryCacheProvider>(Reuse.Singleton);
36-
container.Register<ICacheService, CacheService>(Reuse.Singleton);
37+
container.Register<ICacheProvider, InMemoryCacheProvider>(Reuse.Singleton);
38+
container.Register<ICacheService, CacheService>(Reuse.Singleton);
3739

38-
return container;
39-
}
40+
return container;
41+
}
4042

41-
/// <summary>Registers the in-memory cache from a connection string (scheme must be "memory").</summary>
42-
public static IContainer AddInMemoryCache(this IContainer container, string connectionString)
43-
{
44-
ArgumentNullException.ThrowIfNull(container);
43+
/// <summary>Registers the in-memory cache from a connection string (scheme must be "memory").</summary>
44+
public IContainer AddInMemoryCache(string connectionString)
45+
{
46+
ArgumentNullException.ThrowIfNull(container);
4547

46-
var cs = CacheConnectionString.Parse(connectionString);
48+
var cs = CacheConnectionString.Parse(connectionString);
4749

48-
if (!string.Equals(cs.Scheme, "memory", StringComparison.OrdinalIgnoreCase))
49-
{
50-
throw new ArgumentException(
51-
$"Expected a 'memory://' connection string but got '{cs.Scheme}://'.",
52-
nameof(connectionString)
53-
);
54-
}
50+
if (!string.Equals(cs.Scheme, "memory", StringComparison.OrdinalIgnoreCase))
51+
{
52+
throw new ArgumentException(
53+
$"Expected a 'memory://' connection string but got '{cs.Scheme}://'.",
54+
nameof(connectionString)
55+
);
56+
}
5557

56-
return container.AddInMemoryCache(cs.ToCacheOptions());
58+
return container.AddInMemoryCache(cs.ToCacheOptions());
59+
}
5760
}
5861
}

src/SquidStd.Core/Extensions/Directories/DirectoriesExtension.cs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,26 @@ namespace SquidStd.Core.Extensions.Directories;
77
/// </summary>
88
public static class DirectoriesExtension
99
{
10-
/// <summary>
11-
/// Resolves path by expanding tilde (~) to user home directory and expanding environment variables
12-
/// </summary>
1310
/// <param name="path">The path to resolve</param>
14-
/// <returns>The fully resolved path with expanded environment variables</returns>
15-
/// <exception cref="ArgumentException">Thrown when path is null or empty</exception>
16-
public static string ResolvePathAndEnvs(this string path)
11+
extension(string path)
1712
{
18-
if (string.IsNullOrWhiteSpace(path))
13+
/// <summary>
14+
/// Resolves path by expanding tilde (~) to user home directory and expanding environment variables
15+
/// </summary>
16+
/// <returns>The fully resolved path with expanded environment variables</returns>
17+
/// <exception cref="ArgumentException">Thrown when path is null or empty</exception>
18+
public string ResolvePathAndEnvs()
1919
{
20-
return null;
21-
}
20+
if (string.IsNullOrWhiteSpace(path))
21+
{
22+
return null;
23+
}
2224

23-
path = path.Replace("~", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile));
25+
path = path.Replace("~", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile));
2426

25-
path = Environment.ExpandEnvironmentVariables(path).ExpandEnvironmentVariables();
27+
path = Environment.ExpandEnvironmentVariables(path).ExpandEnvironmentVariables();
2628

27-
return path;
29+
return path;
30+
}
2831
}
2932
}

0 commit comments

Comments
 (0)