Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CronCraft.Test/CronCraft.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.6" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="MSTest" Version="3.6.4" />
</ItemGroup>
Expand Down
53 changes: 53 additions & 0 deletions CronCraft.Test/ServiceCollectionExtensionsTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using CronCraft.Extensions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;

namespace CronCraft.Test;

[TestClass]
public sealed class ServiceCollectionExtensionsTest
{
[TestMethod]
public void AddCronCraft_RegistersServiceAsSingleton()
{
var services = new ServiceCollection();
services.AddCronCraft();

using var provider = services.BuildServiceProvider();

var first = provider.GetRequiredService<CronCraftService>();
var second = provider.GetRequiredService<CronCraftService>();

Assert.AreSame(first, second);
}

[TestMethod]
public void AddCronCraft_AppliesConfiguration()
{
var services = new ServiceCollection();
services.AddCronCraft(settings =>
{
settings.Language = "en";
settings.DayNameFormat = "full";
});

using var provider = services.BuildServiceProvider();

var options = provider.GetRequiredService<IOptions<Models.CronSettings>>();
var cronCraft = provider.GetRequiredService<CronCraftService>();

Assert.AreEqual("en", options.Value.Language);
Assert.AreEqual("full", options.Value.DayNameFormat);
Assert.AreEqual("Every Monday at 09:00 AM", cronCraft.Convert("0 9 * * 1"));
}

[TestMethod]
public void AddCronCraft_ReturnsServiceCollectionForChaining()
{
var services = new ServiceCollection();

var result = services.AddCronCraft();

Assert.AreSame(services, result);
}
}
1 change: 1 addition & 0 deletions CronCraft/CronCraft.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.6" />
<PackageReference Include="Microsoft.Extensions.Options" Version="9.0.6" />
</ItemGroup>

Expand Down
31 changes: 31 additions & 0 deletions CronCraft/Extensions/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using CronCraft.Models;
using Microsoft.Extensions.DependencyInjection;

namespace CronCraft.Extensions;

public static class ServiceCollectionExtensions
{
/// <summary>
/// Adds CronCraft and its configuration options to the service collection.
/// </summary>
/// <param name="services">The service collection to add CronCraft to.</param>
/// <param name="configure">
/// An optional delegate used to configure <see cref="CronSettings"/>.
/// </param>
/// <returns>The service collection so that additional calls can be chained.</returns>
public static IServiceCollection AddCronCraft(
this IServiceCollection services,
Action<CronSettings>? configure = null)
{
ArgumentNullException.ThrowIfNull(services);

services.AddOptions<CronSettings>();

if (configure is not null)
services.Configure(configure);

services.AddSingleton<CronCraftService>();

return services;
}
}
27 changes: 26 additions & 1 deletion CronCraft/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ CronCraft is designed for **clarity, speed, and minimal setup**.

Whether you're building a **web app**, a **CLI tool**, a **Windows Service**, or a **background worker** — just create a `CronSettings` object, and you're good to go.

> ❝ No dependency injection. No appsettings. Just clean, functional cron parsing. ❞
> ❝ No dependency injection required. No appsettings. Just clean, functional cron parsing. ❞

---

Expand All @@ -21,6 +21,7 @@ Whether you're building a **web app**, a **CLI tool**, a **Windows Service**, or
- 🌍 Localized day-of-week formatting (`short`, `full`, `single`, or custom)
- 🕘 Time zone adjustment (optional)
- 🔧 Fully configurable via `CronSettings` object
- 💉 Optional dependency injection registration with `AddCronCraft`
- 📦 Lightweight, zero-dependency core logic

---
Expand Down Expand Up @@ -64,6 +65,30 @@ Console.WriteLine($"📖 Human Readable (Local TZ): {humanReadable}");
Console.ReadLine();
```

### Dependency Injection

For ASP.NET Core and generic host applications, register CronCraft through
`IServiceCollection`:

```csharp
using CronCraft.Extensions;

builder.Services.AddCronCraft(settings =>
{
settings.Language = "en";
settings.DayNameFormat = "short";
});
```

Then inject `CronCraftService` where it is needed:

```csharp
public class MyScheduler(CronCraftService cronCraft)
{
public string Describe(string expression) => cronCraft.Convert(expression);
}
```

**Expected Output:**

```
Expand Down
27 changes: 26 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ CronCraft is designed for **clarity, speed, and minimal setup**.

Whether you're building a **web app**, a **CLI tool**, a **Windows Service**, or a **background worker** — just create a `CronSettings` object, and you're good to go.

> ❝ No dependency injection. No appsettings. Just clean, functional cron parsing. ❞
> ❝ No dependency injection required. No appsettings. Just clean, functional cron parsing. ❞

---

Expand All @@ -21,6 +21,7 @@ Whether you're building a **web app**, a **CLI tool**, a **Windows Service**, or
- 🌍 Localized day-of-week formatting (`short`, `full`, `single`, or custom)
- 🕘 Time zone adjustment (optional)
- 🔧 Fully configurable via `CronSettings` object
- 💉 Optional dependency injection registration with `AddCronCraft`
- 📦 Lightweight, zero-dependency core logic

---
Expand Down Expand Up @@ -64,6 +65,30 @@ Console.WriteLine($"📖 Human Readable (Local TZ): {humanReadable}");
Console.ReadLine();
```

### Dependency Injection

For ASP.NET Core and generic host applications, register CronCraft through
`IServiceCollection`:

```csharp
using CronCraft.Extensions;

builder.Services.AddCronCraft(settings =>
{
settings.Language = "en";
settings.DayNameFormat = "short";
});
```

Then inject `CronCraftService` where it is needed:

```csharp
public class MyScheduler(CronCraftService cronCraft)
{
public string Describe(string expression) => cronCraft.Convert(expression);
}
```

**Expected Output:**

```
Expand Down
Loading