Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
14cdd1c
Remove SimpleInjector dependency
neoscie Oct 3, 2024
f4d80dd
Downgrade Scrutor
neoscie Oct 3, 2024
9365c55
Upgrade Scrutor
neoscie Jul 17, 2025
4f65ae3
Bump several NuGet package dependencies to their latest versions.
neoscie Jul 17, 2025
829c3f5
cleanup
neoscie Jul 17, 2025
4803382
Update the data seeding logic to correctly handle abstract seed types
neoscie Jul 17, 2025
6f72bb6
cleanup
neoscie Jul 17, 2025
58fbd3d
add another test
neoscie Jul 17, 2025
f4ddb33
Implement robust multi-dependency support and circular dependency det…
neoscie Jul 24, 2025
6459cd1
Enables scoped service injection for seeds
neoscie Jul 24, 2025
6eaf858
Moves fake services to dedicated folder
neoscie Jul 24, 2025
16f5012
Simplifies seed retrieval logic
neoscie Jul 24, 2025
202e5b0
feat: enable scoped service injection in seeds for console applications
neoscie Jul 24, 2025
a45da2c
Adds scoped service lifetime handling tests
neoscie Jul 24, 2025
d6c9c4d
Merge branch 'feature/remove-simpleinjector' into feature/multi-depen…
neoscie Jul 26, 2025
727952c
Update README.md to reflect latest improvements
neoscie Jul 26, 2025
b4aa19d
Refactors unit tests and adds circular dependency tests
neoscie Jul 26, 2025
43f3ea5
Fix CA issues, add test
neoscie Jul 27, 2025
403169d
cleanup
neoscie Jul 27, 2025
d8742fb
Removes deprecated `Priority` and `DependsOn` properties from `ISeed`…
neoscie Jul 27, 2025
b27b135
Merge remote-tracking branch 'origin/main' into feature/multi-dependency
neoscie Jul 27, 2025
876b031
Merge remote-tracking branch 'origin/main' into feature/multi-dependency
neoscie Jul 27, 2025
29529b3
cleanup
neoscie Jul 27, 2025
ae03032
Adds demo data seeding implementation
neoscie Jul 27, 2025
b6cfca5
Simplifies data seeding demo and fixes build errors
neoscie Jul 27, 2025
5484f13
Simplifies seed dependency declaration with `DependsOnAttribute`
neoscie Jul 27, 2025
0bd3426
Updates to .NET 8 across projects
neoscie Jul 28, 2025
8d9c2f4
Updates and removes package references
neoscie Jul 28, 2025
d034593
cleanup
neoscie Jul 28, 2025
13df6c0
cleanup
neoscie Jul 28, 2025
8fcf0f9
Enforces unique seed type registration
neoscie Aug 4, 2025
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
10 changes: 5 additions & 5 deletions .github/workflows/dotnet-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ name: Publish NuGet package

on:
push:
tags:
tags:
- 'v*.*.*'
workflow_dispatch:

env:
ARTIFACTS_FEED_URL: https://api.nuget.org/v3/index.json
BUILD_CONFIGURATION: "Release"
DOTNET_VERSION: "6.x"
DOTNET_VERSION: "8.x"

jobs:
build-and-deploy:
Expand All @@ -28,14 +28,14 @@ jobs:
source-url: ${{ env.ARTIFACTS_FEED_URL }}
env:
NUGET_AUTH_TOKEN: ${{ secrets.NUGET_API_KEY_NEOLUTION }}

- name: Install GitVersion
uses: gittools/actions/gitversion/setup@v0.9.7
with:
versionSpec: '5.10.3'

- name: Determine version number
uses: gittools/actions/gitversion/execute@v0.9.7
uses: gittools/actions/gitversion/execute@v0.9.7

- name: Build and pack
run: |
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: CI

on:
on:
push:
branches: [ main ]
pull_request:
Expand All @@ -9,7 +9,7 @@ on:

env:
BUILD_CONFIGURATION: "Release"
DOTNET_VERSION: "6.x"
DOTNET_VERSION: "8.x"

jobs:
build:
Expand Down
3 changes: 3 additions & 0 deletions Neolution.Extensions.DataSeeding.Demo/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[*.{cs,vb}]
# There is no synchronization context in our console apps, so we do not need to use ConfigureAwait(false)
dotnet_diagnostic.CA2007.severity = none
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace Neolution.Extensions.DataSeeding.Sample.Commands.Init
namespace Neolution.Extensions.DataSeeding.Demo.Commands.Init
{
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Neolution.DotNet.Console.Abstractions;
Expand All @@ -9,7 +10,7 @@
/// <summary>
/// The data initializer.
/// </summary>
public class InitCommand : IAsyncConsoleAppCommand<InitOptions>
public class InitCommand : IDotNetConsoleCommand<InitOptions>
{
/// <summary>
/// The logger
Expand All @@ -33,31 +34,24 @@ public InitCommand(ILogger<InitCommand> logger, ISeeder seeder)
}

/// <inheritdoc />
public Task RunAsync(InitOptions options)
public Task RunAsync(InitOptions options, CancellationToken cancellationToken)
{
if (options is null)
{
throw new ArgumentNullException(nameof(options));
}

return this.RunInternalAsync();
}
return RunInternalAsync();

/// <summary>
/// Runs the command asynchronously.
/// </summary>
/// <returns>An awaitable <see cref="Task"/>.</returns>
private async Task RunInternalAsync()
{
this.logger.LogInformation("Start data initializer...");

// Automatic seeding
await this.seeder.SeedAsync().ConfigureAwait(true);
async Task RunInternalAsync()
{
this.logger.LogInformation("Start data initializer...");

// Manual seeding
await this.seeder.SeedAsync<MySeed>().ConfigureAwait(true);
// Automatic seeding
await this.seeder.SeedAsync();

this.logger.LogInformation("Data initializer finished!");
this.logger.LogInformation("Data initializer finished!");
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Neolution.Extensions.DataSeeding.Sample.Commands.Init
namespace Neolution.Extensions.DataSeeding.Demo.Commands.Init
{
using CommandLine;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
namespace Neolution.Extensions.DataSeeding.Demo.Commands.Init.Seeds
{
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Neolution.Extensions.DataSeeding.Abstractions;

/// <summary>
/// Creates content categories for organizing articles and pages
/// Depends on system configuration for category settings
/// </summary>
[DependsOn(typeof(SystemConfigurationSeed))]
public class CategoriesSeed : ISeed
{
/// <summary>
/// The logger
/// </summary>
private readonly ILogger<CategoriesSeed> logger;

/// <summary>
/// Initializes a new instance of the <see cref="CategoriesSeed"/> class.
/// </summary>
/// <param name="logger">The logger.</param>
public CategoriesSeed(ILogger<CategoriesSeed> logger)
{
this.logger = logger;
}

/// <inheritdoc />
public async Task SeedAsync()
{
this.logger.LogInformation("Creating content categories: News, Blog, Products, About...");
await Task.Delay(120);
this.logger.LogInformation("Content categories created successfully");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
namespace Neolution.Extensions.DataSeeding.Demo.Commands.Init.Seeds
{
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Neolution.Extensions.DataSeeding.Abstractions;

/// <summary>
/// Creates content metadata and SEO tags
/// Has no dependencies but is used by ContentSeed for metadata assignment
/// </summary>
public class ContentMetadataSeed : ISeed
{
/// <summary>
/// The logger
/// </summary>
private readonly ILogger<ContentMetadataSeed> logger;

/// <summary>
/// Initializes a new instance of the <see cref="ContentMetadataSeed"/> class.
/// </summary>
/// <param name="logger">The logger.</param>
public ContentMetadataSeed(ILogger<ContentMetadataSeed> logger)
{
this.logger = logger;
}

/// <inheritdoc />
public async Task SeedAsync()
{
this.logger.LogInformation("Creating SEO metadata templates: title patterns, meta descriptions...");
await Task.Delay(150);
this.logger.LogInformation("Setting up content tags: technology, business, tutorial, news...");
await Task.Delay(100);
this.logger.LogInformation("Configuring schema.org structured data templates...");
await Task.Delay(100);
this.logger.LogInformation("Content metadata and SEO configuration completed");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
namespace Neolution.Extensions.DataSeeding.Demo.Commands.Init.Seeds
{
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Neolution.Extensions.DataSeeding.Abstractions;

/// <summary>
/// Creates sample content including pages and articles
/// Depends on both categories and users being available (demonstrates multiple dependencies)
/// </summary>
[DependsOn(typeof(CategoriesSeed), typeof(UsersSeed), typeof(ContentTemplatesSeed), typeof(ContentMetadataSeed))]
public class ContentSeed : ISeed
{
/// <summary>
/// The logger
/// </summary>
private readonly ILogger<ContentSeed> logger;

/// <summary>
/// Initializes a new instance of the <see cref="ContentSeed"/> class.
/// </summary>
/// <param name="logger">The logger.</param>
public ContentSeed(ILogger<ContentSeed> logger)
{
this.logger = logger;
}

/// <inheritdoc />
public async Task SeedAsync()
{
this.logger.LogInformation("Creating sample content: Home page, About page, sample blog posts...");
await Task.Delay(250);
this.logger.LogInformation("Sample content created and assigned to categories and authors");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
namespace Neolution.Extensions.DataSeeding.Demo.Commands.Init.Seeds
{
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Neolution.Extensions.DataSeeding.Abstractions;

/// <summary>
/// Creates content templates and workflow configurations
/// Depends on UserRolesSeed for permission setup, used by ContentSeed and MenusSeed
/// </summary>
[DependsOn(typeof(UserRolesSeed))]
public class ContentTemplatesSeed : ISeed
{
/// <summary>
/// The logger
/// </summary>
private readonly ILogger<ContentTemplatesSeed> logger;

/// <summary>
/// Initializes a new instance of the <see cref="ContentTemplatesSeed"/> class.
/// </summary>
/// <param name="logger">The logger.</param>
public ContentTemplatesSeed(ILogger<ContentTemplatesSeed> logger)
{
this.logger = logger;
}

/// <inheritdoc />
public async Task SeedAsync()
{
this.logger.LogInformation("Creating content templates: Article template, Page template, Blog post template...");
await Task.Delay(200);
this.logger.LogInformation("Setting up content workflows: Draft → Review → Published states...");
await Task.Delay(150);
this.logger.LogInformation("Configuring template permissions based on user roles...");
await Task.Delay(100);
this.logger.LogInformation("Content templates and workflows created successfully");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
namespace Neolution.Extensions.DataSeeding.Demo.Commands.Init.Seeds
{
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Neolution.Extensions.DataSeeding.Abstractions;

/// <summary>
/// Sets up the database schema and initial configuration
/// This seed runs first and has no dependencies
/// </summary>
public class DatabaseMigrationSeed : ISeed
{
/// <summary>
/// The logger
/// </summary>
private readonly ILogger<DatabaseMigrationSeed> logger;

/// <summary>
/// Initializes a new instance of the <see cref="DatabaseMigrationSeed"/> class.
/// </summary>
/// <param name="logger">The logger.</param>
public DatabaseMigrationSeed(ILogger<DatabaseMigrationSeed> logger)
{
this.logger = logger;
}

/// <inheritdoc />
public async Task SeedAsync()
{
this.logger.LogInformation("Setting up database schema: creating tables for users, content, categories, menus...");
await Task.Delay(200);
this.logger.LogInformation("Database migration completed successfully");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
namespace Neolution.Extensions.DataSeeding.Demo.Commands.Init.Seeds
{
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Neolution.Extensions.DataSeeding.Abstractions;

/// <summary>
/// Uploads sample media files like images and documents
/// Has no dependencies and can run independently
/// </summary>
public class MediaFilesSeed : ISeed
{
/// <summary>
/// The logger
/// </summary>
private readonly ILogger<MediaFilesSeed> logger;

/// <summary>
/// Initializes a new instance of the <see cref="MediaFilesSeed"/> class.
/// </summary>
/// <param name="logger">The logger.</param>
public MediaFilesSeed(ILogger<MediaFilesSeed> logger)
{
this.logger = logger;
}

/// <inheritdoc />
public async Task SeedAsync()
{
this.logger.LogInformation("Uploading sample media files: logo.png, hero-image.jpg, sample-document.pdf...");
await Task.Delay(300);
this.logger.LogInformation("Sample media files uploaded to media library");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
namespace Neolution.Extensions.DataSeeding.Demo.Commands.Init.Seeds
{
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Neolution.Extensions.DataSeeding.Abstractions;

/// <summary>
/// Sets up media processing configuration and creates thumbnails for uploaded media files
/// Depends on MediaFilesSeed to have files available for processing
/// </summary>
[DependsOn(typeof(MediaFilesSeed))]
public class MediaProcessingSeed : ISeed
{
/// <summary>
/// The logger
/// </summary>
private readonly ILogger<MediaProcessingSeed> logger;

/// <summary>
/// Initializes a new instance of the <see cref="MediaProcessingSeed"/> class.
/// </summary>
/// <param name="logger">The logger.</param>
public MediaProcessingSeed(ILogger<MediaProcessingSeed> logger)
{
this.logger = logger;
}

/// <inheritdoc />
public async Task SeedAsync()
{
this.logger.LogInformation("Configuring media processing settings: thumbnail sizes, compression levels...");
await Task.Delay(200);
this.logger.LogInformation("Generating thumbnails for uploaded media files...");
await Task.Delay(300);
this.logger.LogInformation("Media processing configuration completed and thumbnails generated");
}
}
}
Loading