diff --git a/.tasks.json b/.tasks.json new file mode 100644 index 0000000..f694204 --- /dev/null +++ b/.tasks.json @@ -0,0 +1,13 @@ +{ + "Tasks": [ + { + "Title": "Generate README for FluentCMS.Infrastructure.Common", + "AgentName": "DocumentationGenerator", + "DetailedInstructions": "Create a README.md file in the project root (src/Common/FluentCMS.Infrastructure.Common/) for NuGet publishing. Include: project description as common utilities for FluentCMS Infrastructure, key features (shared base classes, utilities), installation via NuGet (dotnet add package FluentCMS.Infrastructure.Common), basic usage example, dependencies (none external), and MIT license reference.", + "ContextPath": "src/Common/FluentCMS.Infrastructure.Common/", + "Priority": 5, + "Status": 0 + } + ], + "CreatedAt": "2026-02-09T08:45:35.5079343Z" +} \ No newline at end of file diff --git a/README.md b/README.md index 73a1966..6ab6a4e 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,84 @@ -# FluentCMS.Infrastructure -FluentCMS Infrastructure +# Plugins + +> A modular plugin system for FluentCMS infrastructure, enabling dynamic discovery, loading, and initialization of plugins to extend core functionality. + +## 📖 About +The Plugins project is a collection of libraries that enable a flexible plugin architecture for FluentCMS. It provides mechanisms for discovering plugins from directories, loading them in isolated AssemblyLoadContexts to prevent memory leaks, initializing plugin instances, and managing their lifecycles. This allows developers to extend the CMS capabilities dynamically without modifying the core codebase, ensuring modularity, safety, and ease of integration. + +## 🚀 Getting Started + +### Prerequisites +* .NET 10.0 + +### Installation +```bash +# Build the projects +dotnet build FluentCMS.Infrastructure.Plugins.Abstractions.csproj +dotnet build FluentCMS.Infrastructure.Plugins.csproj +``` + +Since this project consists of multiple .NET libraries, build them and reference the resulting assemblies in your application. + +### Setup +Configure the plugin system in your application: + +```csharp +using FluentCMS.Infrastructure.Plugins; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddPluginSystem(options => +{ + // Configure options, e.g. + options.PluginDirectories = ["path/to/plugins"]; +}); +var app = builder.Build(); +app.UsePluginSystem(); +``` + +### Usage Examples +To create a plugin, implement the `IPluginStartup` interface from `FluentCMS.Infrastructure.Plugins.Abstractions`, and mark the class with the `Plugin` attribute. + +Example plugin: +```csharp +using FluentCMS.Infrastructure.Plugins.Abstractions; + +[Plugin] +public class MyPlugin : IPluginStartup +{ + public void ConfigureServices(IServiceCollection services, IConfiguration? configuration) + { + // Register plugin-specific services + services.AddScoped(); + } + + public void Configure(IApplicationBuilder app) + { + // Configure middleware or routes + app.MapGet("/myplugin", () => "Hello from Plugin!"); + } + + // Optionally override Name, Version, Priorities + public override string Name => "My Custom Plugin"; +} +``` + +Build this as a separate assembly and place it in a directory configured in `PluginDirectories`. + +The system will discover, load, initialize, and start the plugin automatically. + +## 📦 Key Features +- **Dynamic Discovery**: Scans directories for plugin assemblies based on file patterns. +- **Isolated Loading**: Uses custom `AssemblyLoadContext` to load plugins collectibly, preventing memory leaks and allowing unloading. +- **Initialization and Lifecycle**: Handles plugin instantiation, service registration, and application configuration with priority ordering. +- **Error Handling**: Provides robust exception handling, logging, and optional error ignoring for resilient operation. +- **Abstraction-Based Design**: Extensible through interfaces like `IPluginDiscovery`, `IPluginLoader`, `IPluginInitializer`, and `IPluginManager`. +- **Configuration Scoping**: Each plugin receives its own configuration section under 'Plugins:{PluginName}'. + +## 📚 Dependencies +Key dependencies include: +- .NET 10.0 +- Microsoft.AspNetCore.Http.Abstractions (2.3.9) +- Microsoft.Extensions.Configuration.Abstractions (10.0.2) +- Microsoft.Extensions.DependencyInjection.Abstractions (10.0.2) +- Microsoft.Extensions.Logging.Abstractions (10.0.2) +- System.Reflection.MetadataLoadContext (10.0.2) \ No newline at end of file diff --git a/llm.json b/llm.json new file mode 100644 index 0000000..2179763 --- /dev/null +++ b/llm.json @@ -0,0 +1,2235 @@ +{ + "ProjectMap": { + "Name": ".", + "Path": "", + "FolderSummary": "The root folder is responsible for containing the project\u0027s configuration files (like .gitignore and .tasks.json for build and exclusion rules), legal documentation (such as the LICENSE file), and the primary source code subfolder (src).", + "Files": [ + { + "Name": ".gitignore", + "Summary": { + "Summary": "This .gitignore file configures Git to ignore files and directories specific to Visual Studio development, including temporary files, build results, and artifacts from various add-ons to prevent them from being committed to version control.", + "Exceptions": "The file includes explicit exceptions for certain files and directories, such as !Directory.Build.rsp, !**/[Pp]ackages/build/, and VSCode settings files, allowing them to be tracked despite matching ignore patterns.", + "Features": "Implements comprehensive ignore patterns for user-specific files, build outputs, cache directories, test results, package outputs, and artifacts from tools like ReSharper, NUnit, and AWS SAM to ensure clean repositories.", + "Roles": [ + "Configuration", + "Exclusion Rule" + ], + "Hash": "3407CEFC2A9D64F884FF3122A5ADE50C10D001D10F608062C20FF92B225AE436" + } + }, + { + "Name": "LICENSE", + "Summary": { + "Summary": "This file contains the MIT License for FluentCMS, granting users permission to use, copy, modify, merge, publish, distribute, sublicense, and sell the software under the specified conditions.", + "Exceptions": "The copyright year is listed as 2026, which appears to be a future date.", + "Features": "Grants permissions for free use, modification, and redistribution of the software, with requirements to include copyright and permission notices.", + "Roles": [ + "Legal Document" + ], + "Hash": "83F0902AE5BC89A9A0CC37F9B4DA115F3C0418EC270423726E13241138F6D623" + } + }, + { + "Name": ".tasks.json", + "Summary": { + "Summary": "This JSON file defines a list of tasks for generating README documentation for various FluentCMS Infrastructure NuGet packages, each specifying details like agent, instructions, and context.", + "Exceptions": "The CreatedAt timestamp is dated in the future (2026-02-09), which may indicate it\u0027s a planned or mock configuration.", + "Features": "Task definitions with titles, assigned agents, detailed instructions for README creation, context paths, priorities, and statuses.", + "Roles": [ + "Build Configuration", + "Task List" + ], + "Hash": "3FDA31A25367075B3BD628C2DF45A7A0CC3EFB8D2BF88B537210B9D1933E3B2A" + } + } + ], + "Directories": [ + { + "Name": "src", + "Path": "src", + "FolderSummary": "The \u0060src\u0060 folder houses the source code for the infrastructure module of the FluentCMS project, including core components such as event handling, data repositories, logging, configuration, providers, common utilities, and plugin support.", + "Files": [ + { + "Name": "FluentCMS.Infrastructure.slnx", + "Summary": { + "Summary": "This file is a Visual Studio solution file (.slnx) for the FluentCMS Infrastructure, organizing multiple .NET projects into logical folders based on their functionalities such as Common, Configuration, EventBus, Logging, Plugins, Providers, and Repositories.", + "Exceptions": "The use of .slnx format, which is not the standard .sln file, may be intended for Launch.VS extension support.", + "Features": "Provides modular structuring of projects with abstractions, multiple EntityFramework implementations for Sqlite and SqlServer in Configuration and Repositories, in-memory EventBus with example and test projects, logging, plugin system, and provider repositories.", + "Roles": [ + "Solution Container", + "Project Organizer", + "Infrastructure Module" + ], + "Hash": "3DEB659B877BA0E52C63F68FBA402A308ADA4AD2EBEC8748CBA622A6B36E6266" + } + } + ], + "Directories": [ + { + "Name": "EventBus", + "Path": "src/EventBus", + "FolderSummary": "The EventBus folder provides the core infrastructure for enabling decoupled event-driven communication within the FluentCMS project, including implementations like in-memory event buses, example usages, and associated tests.", + "Files": [], + "Directories": [ + { + "Name": "FluentCMS.Infrastructure.EventBus.Example", + "Path": "src/EventBus/FluentCMS.Infrastructure.EventBus.Example", + "FolderSummary": "The folder \u0022FluentCMS.Infrastructure.EventBus.Example\u0022 serves as a demonstration project for configuring and utilizing the EventBus infrastructure in FluentCMS, including dependency injection, event handling, logging, and performance tracking.", + "Files": [ + { + "Name": "Program.cs", + "Summary": { + "Summary": "The provided code is a C# console application that demonstrates two different modes of an EventBus: Aggregate and FailFast. The application sets up an in-memory EventBus using dependency injection, registers event handlers for UserRegisteredEvent and OrderPlacedEvent, and measures the execution time of event publishing in both modes.", + "Exceptions": "The code does not handle any exceptions explicitly. In Aggregate mode, errors are collected and thrown as an AggregateException. In FailFast mode, execution stops immediately upon the first error.", + "Features": "Key features include:", + "Roles": [ + "EventBus Configuration", + "Dependency Injection Setup", + "Event Handler Registration", + "Logging Integration", + "Performance Measurement" + ], + "Hash": "EAFAC4187A10FCA4B18E4A474E92B40771BC1F48DF1527BF3017124D009EF386" + } + }, + { + "Name": "FluentCMS.Infrastructure.EventBus.Example.csproj", + "Summary": { + "Summary": "Project file for FluentCMS.Infrastructure.EventBus.Example, a .NET 10.0 console application that uses the FluentCMS.Infrastructure.EventBus.InMemory and FluentCMS.Infrastructure.EventBus libraries. It includes logging and dependency injection packages.", + "Exceptions": "None", + "Features": "None", + "Roles": [ + "Project" + ], + "Hash": "7CDD013C88E226F29343C5957F872A14BBE480D407626EE5C649CEFA7B5B23D4" + } + } + ], + "Directories": [ + { + "Name": "Events", + "Path": "src/EventBus/FluentCMS.Infrastructure.EventBus.Example/Events", + "FolderSummary": "The Events folder encapsulates event classes, such as OrderPlacedEvent (serving as both an event and a DTO) and UserRegisteredEvent (associated with users), to facilitate event-driven communication and data transfer within the system.", + "Files": [ + { + "Name": "OrderPlacedEvent.cs", + "Summary": { + "Summary": "OrderPlacedEvent.cs contains a class that represents an event raised when a customer places an order. The class inherits from EventBase and includes four required properties: OrderId (string), CustomerId (string), TotalAmount (decimal), and ItemCount (int). These properties are set during initialization and cannot be modified afterward.", + "Exceptions": "None", + "Features": "The class uses required properties with init accessors, ensuring that all properties must be set when the object is created. This enforces data integrity by preventing uninitialized state.", + "Roles": [ + "Event", + "Data Transfer Object (DTO)" + ], + "Hash": "D1D93797E9F0A0A12335BD616C19BC9F31E54153E82A1295EB95ABF20C9EC6F9" + } + }, + { + "Name": "UserRegisteredEvent.cs", + "Summary": { + "Summary": "Event raised when a new user registers in the system", + "Exceptions": "", + "Features": "This class represents a user registration event. It inherits from EventBase and includes three required string properties: UserId, Email, and FullName.", + "Roles": [ + "User" + ], + "Hash": "9C1F5C7DE420C24391501ADF69D3B873579CA47F216B8CA1F455544E871313BD" + } + } + ], + "Directories": [] + }, + { + "Name": "Handlers", + "Path": "src/EventBus/FluentCMS.Infrastructure.EventBus.Example/Handlers", + "FolderSummary": "The Handlers folder contains classes responsible for processing business logic operations, commands, and events, such as sending order confirmations, updating inventory, creating user profiles, logging activities, and dispatching welcome emails.", + "Files": [ + { + "Name": "SendOrderConfirmationHandler.cs", + "Summary": { + "Summary": "The code file SendOrderConfirmationHandler.cs defines a class that handles the OrderPlacedEvent. It logs information about sending order confirmation emails to customers, including order ID, customer ID, and total amount. The class uses FluentCMS\u0027s event bus infrastructure and includes logging with ILogger. The Handle method simulates a delay of 120 milliseconds and logs the completion of sending the confirmation email. The namespace is FluentCMS.Infrastructure.EventBus.Example.Handlers, and the class implements IEventSubscriber\u003COrderPlacedEvent\u003E.", + "Exceptions": "None", + "Features": "None", + "Roles": [ + "None" + ], + "Hash": "C768F547106C57C5059C6C4494E1E1E1B26D90335D1DFDE2AB87D794CC7BD80B" + } + }, + { + "Name": "UpdateInventoryHandler.cs", + "Summary": { + "Summary": "Updates inventory when an order is placed. It handles the OrderPlacedEvent, logs the process, and simulates a delay before updating inventory successfully. The class uses dependency injection for ILogger and is async in nature.", + "Exceptions": "UpdateInventoryHandler.cs", + "Features": "UpdateInventoryHandler.cs", + "Roles": [ + "UpdateInventoryHandler" + ], + "Hash": "FAFA8DF09712BC501CA1EBF1CC70946A3F37724B6C0B08E87D360185A9A324DE" + } + }, + { + "Name": "CreateUserProfileHandler.cs", + "Summary": { + "Summary": "This file defines an event handler class that responds to a UserRegisteredEvent by logging and simulating the creation of a user profile.", + "Exceptions": "The profile creation is simulated with a delay instead of actual database operations, making it an example implementation.", + "Features": "Implements event subscribing for UserRegisteredEvent, includes logging of user ID and full name, asynchronous handling with cancellation token support, and a simulated delay for profile creation.", + "Roles": [ + "Event Handler", + "Event Subscriber" + ], + "Hash": "22FC4432A9D15EFBD342D0AB851CD7EFC72E1F88FFF6DD5E69725F0A33CA7806" + } + }, + { + "Name": "LogUserActivityHandler.cs", + "Summary": { + "Summary": "The LogUserActivityHandler class logs user activity for audit purposes when a UserRegisteredEvent occurs. It implements the IEventSubscriber interface and uses dependency injection for ILogger. The handler logs the user ID and then simulates a delay before logging additional details including the occurrence time.", + "Exceptions": "None specified in the provided code.", + "Features": "The class includes a constructor that injects ILogger, and a Handle method that processes UserRegisteredEvent. The method logs two messages: one with the user ID and another with the user ID and occurrence time. It includes a simulated delay using Task.Delay.", + "Roles": [ + "Event Subscriber", + "Audit Logging" + ], + "Hash": "8754F9271EEC2C3D3B6D222F247204FDC7F4A1B0BA7A135FE2CEDCBDAA98DB93" + } + }, + { + "Name": "SendWelcomeEmailHandler.cs", + "Summary": { + "Summary": "SendWelcomeEmailHandler.cs is a C# class that implements the IEventSubscriber interface to handle the UserRegisteredEvent. It logs information about sending a welcome email to a newly registered user and simulates a delay before confirming the email was sent successfully. The class uses dependency injection for ILogger and handles the event asynchronously with a CancellationToken.", + "Exceptions": "None", + "Features": "None", + "Roles": [ + "None" + ], + "Hash": "A23B103BAC61492B27D86764CE72A456938D422BAA633DBAEA3780C4D9DFCCDF" + } + } + ], + "Directories": [] + } + ] + }, + { + "Name": "FluentCMS.Infrastructure.EventBus.InMemory", + "Path": "src/EventBus/FluentCMS.Infrastructure.EventBus.InMemory", + "FolderSummary": "The FluentCMS.Infrastructure.EventBus.InMemory folder implements an in-memory event bus component for the FluentCMS project, handling event publishing, error management, and service registration without relying on external infrastructure.", + "Files": [ + { + "Name": "FluentCMS.Infrastructure.EventBus.InMemory.csproj", + "Summary": { + "Summary": "Project file for FluentCMS.Infrastructure.EventBus.InMemory", + "Exceptions": "None", + "Features": "None", + "Roles": [ + "Project" + ], + "Hash": "1FC41ECEA8F7A9291555155AB8D21EA21F6B2B64606B484A160A83CA427EA5D2" + } + }, + { + "Name": "Exceptions.cs", + "Summary": { + "Summary": "EventPublisherAggregatedException is a custom exception class designed to handle multiple exceptions thrown by event handlers for a specific event type. It inherits from AggregateException and provides a way to aggregate exceptions from multiple handlers for a given event type TEvent.", + "Exceptions": "None", + "Features": "This class aggregates exceptions from multiple event handlers for a specific event type. It provides a custom message that includes the name of the event type and allows for easy identification of the event type that caused the aggregated exceptions.", + "Roles": [ + "Exception Aggregator", + "Event Handler Exception Handler" + ], + "Hash": "25E9F498C56B248691185693BBFEB8E180782F84A4D7CD2E6E627E435339E5A8" + } + }, + { + "Name": "ServiceCollectionExtensions.cs", + "Summary": { + "Summary": "Registers the generic event publisher and returns the services collection.", + "Exceptions": "ArgumentNullException.ThrowIfNull(services)", + "Features": "Configure options with default or provided configuration", + "Roles": [ + "services.TryAddSingleton\u003CIEventPublisher, EventPublisher\u003E()" + ], + "Hash": "D143437DEEE277667D201AF06BD4281F583C8FF6CECF086C7622F7830EDC7554" + } + }, + { + "Name": "EventPublisher.cs", + "Summary": { + "Summary": "In-memory event publisher implementation that invokes event handlers directly. Suitable for low latency scenarios with manageable event handlers. Registered as a singleton service.", + "Exceptions": "EventPublisherAggregatedException\u003CTEvent\u003E", + "Features": "In-memory event publisher, sequential or concurrent execution, error handling modes (FailFast or Aggregate), scope management, logging", + "Roles": [ + "EventPublisher", + "IEventPublisher" + ], + "Hash": "B3D2E771D77E61D1F7E5197833E099784CB429C5ABF6F616E98E86C2E8000EE7" + } + }, + { + "Name": "_GlobalUsings.cs", + "Summary": { + "Summary": "The code file contains global using directives for various namespaces. The JSON should list each one.", + "Exceptions": "The JSON must be valid. Ensure proper formatting and escaping if needed.", + "Features": "The JSON should represent the using directives as an array of objects with \u0027using\u0027 keys.", + "Roles": [ + "The user expects a JSON output with the using directives parsed correctly." + ], + "Hash": "F3C5EC7C4D594B250197958FC02FAF8BD280B1D04B9C2543A5B878793A5B0DB9" + } + }, + { + "Name": "EventPublisherOptions.cs", + "Summary": { + "Summary": "Options for configuring the event publisher.", + "Exceptions": "Defines how exceptions from event handlers are handled.", + "Features": "Handlers execute SEQUENTIALLY in registration order for FailFast, or CONCURRENTLY for Aggregate.", + "Roles": [ + "EventPublisherOptions", + "ErrorHandlingMode" + ], + "Hash": "A5EB786E45102BD2221F8EF7E4B47462D5F50A93987B0C9B7CB23C85C2B270BD" + } + } + ], + "Directories": [] + }, + { + "Name": "FluentCMS.Infrastructure.EventBus.Tests", + "Path": "src/EventBus/FluentCMS.Infrastructure.EventBus.Tests", + "FolderSummary": "This folder contains unit tests for the EventBus infrastructure component of FluentCMS, verifying event publishing, handling, and service configurations using test classes and an in-memory subfolder for isolated testing.", + "Files": [ + { + "Name": "ServiceCollectionExtensionsTests.cs", + "Summary": { + "Summary": "The ServiceCollectionExtensionsTests class contains tests for the AddEventHandler method in the FluentCMS Infrastructure EventBus. The tests verify that the method handles null services, registers handlers as scoped, returns the service collection, allows multiple handlers for the same event, and resolves handlers from a service provider.", + "Exceptions": "ArgumentNullException", + "Features": "AddEventHandler", + "Roles": [ + "TestEvent", + "TestEventHandler", + "AnotherTestEventHandler" + ], + "Hash": "B9AE66225A7E2EEE340D937038CD3B3F3E7F21FC7198A126C70CDA499FE7BB5E" + } + }, + { + "Name": "FluentCMS.Infrastructure.EventBus.Tests.csproj", + "Summary": { + "Summary": "Project file for FluentCMS.Infrastructure.EventBus.Tests, targeting .NET 10.0 with test dependencies.", + "Exceptions": "None", + "Features": "None", + "Roles": [ + "Project", + "Test Project" + ], + "Hash": "184EF32A7F265633028ABFB49830C6467AA5156E8988F4DB9814AD44B50A62C4" + } + }, + { + "Name": "_GlobalUsings.cs", + "Summary": { + "Summary": "This C# file defines global using directives, making various namespaces\u2014such as those for testing, mocking, dependency injection, and custom event bus components\u2014available throughout the project without explicit using statements in each file.", + "Exceptions": "No exceptions or unexpected inclusions; all global usings appear standard for a modern C# project involving unit testing and infrastructure components.", + "Features": "Exports global access to namespaces for unit testing (Xunit), assertions (FluentAssertions), mocking (Moq), dependency injection (Microsoft.Extensions.DependencyInjection and Microsoft.Extensions.Options), ASP.NET Core Http services, and custom event bus abstractions (FluentCMS event bus).", + "Roles": [ + "Configuration", + "Utility" + ], + "Hash": "80026D7E75605FCE87EC5186FF37219733E94B043BF99F1206BA7E07510CCDC2" + } + }, + { + "Name": "EventBaseTests.cs", + "Summary": { + "Summary": "This file contains unit tests for the EventBase class in the FluentCMS Infrastructure EventBus namespace, verifying its constructor behavior, property initialization, uniqueness of event IDs, interface implementation, and support for derived events.", + "Exceptions": "None; the file appears to be a standard unit test suite.", + "Features": "Tests for setting OccurredAt timestamp, generating non-empty and unique EventId, implementing IEvent interface, enforcing init-only properties, and allowing inheritance in derived events.", + "Roles": [ + "Unit Test", + "Test Suite" + ], + "Hash": "032A5420D7DF22AFF4729D074C42D60FB38122337866F067E63B34BE73961A0E" + } + } + ], + "Directories": [ + { + "Name": "InMemory", + "Path": "src/EventBus/FluentCMS.Infrastructure.EventBus.Tests/InMemory", + "FolderSummary": "This folder contains unit tests for the in-memory event publishing system, covering event dispatching to subscribers, ServiceCollection extensions, aggregated exception handling, and configuration options.", + "Files": [ + { + "Name": "EventPublisherTests.cs", + "Summary": { + "Summary": "publish_failfastmode_shouldstoponfirstexception", + "Exceptions": "publish_should_throw_argumentnullexception_wheneventisnull", + "Features": "publish_should_throw_operationcanceledexception_whencancellationrequested", + "Roles": [ + "publish_should_invoke_all_subscribers_whenmultiplesubscribersexist" + ], + "Hash": "F13BC0B3C9253A138CFA7FCA924C5894866B7D0247A7861ECC93303BF7CE24EC" + } + }, + { + "Name": "ServiceCollectionExtensionsTests.cs", + "Summary": { + "Summary": "Analysis of ServiceCollectionExtensionsTests.cs file, which contains unit tests for the AddInMemoryEventBus method in the FluentCMS Infrastructure EventBus InMemory module.", + "Exceptions": "The tests cover various scenarios including null service checks, service registration, configuration options, and fluent configuration.", + "Features": "The tests validate the behavior of the AddInMemoryEventBus method, ensuring it handles null inputs, registers services correctly, applies default and custom configurations, and prevents duplicate registrations.", + "Roles": [ + "ServiceCollectionExtensionsTests" + ], + "Hash": "887DC25844CA9085102025C8480101DFE79137B74ED1D441051A77CBFD0991C7" + } + }, + { + "Name": "EventPublisherAggregatedExceptionTests.cs", + "Summary": { + "Summary": "This file contains unit tests for the EventPublisherAggregatedException class, verifying its constructor functionality, event type assignment, message content, inheritance, and handling of multiple or empty exceptions in the context of an in-memory event bus.", + "Exceptions": "A nested TestEvent class inheriting from EventBase is included solely for testing purposes within the test class.", + "Features": "Unit tests implementing validation of constructor for setting inner exceptions, event type, custom message including event type name, assignability to AggregateException, handling of multiple exceptions in order, and creation with empty exception collection.", + "Roles": [ + "Unit Test" + ], + "Hash": "F46BB65973EA61A4497DD8893D3C26FF620D3A17D442B24FAA1B46771F6E2246" + } + }, + { + "Name": "EventPublisherOptionsTests.cs", + "Summary": { + "Summary": "This file contains unit tests for the EventPublisherOptions class in the FluentCMS infrastructure, verifying the default error handling mode, the ability to set the mode via a setter, and the properties of the ErrorHandlingMode enum including its values and integer representations.", + "Exceptions": "", + "Features": "Unit tests for default mode initialization to Aggregate, mode setter functionality for FailFast and Aggregate, enum value count (2 values), and specific enum value mappings (FailFast=0, Aggregate=1).", + "Roles": [ + "Test" + ], + "Hash": "92B7A6D823F764EAA71DBBDA3E06D80BD47492CDDC962D0BF02F305A81320910" + } + } + ], + "Directories": [] + } + ] + }, + { + "Name": "FluentCMS.Infrastructure.EventBus", + "Path": "src/EventBus/FluentCMS.Infrastructure.EventBus", + "FolderSummary": "This folder implements the infrastructure for an event bus in the FluentCMS project, providing a base class for domain events, service collection extensions, and abstractions to facilitate decoupled messaging between components.", + "Files": [ + { + "Name": "EventBase.cs", + "Summary": { + "Summary": "Base class for domain events with common properties", + "Exceptions": "", + "Features": "This class provides a base implementation for domain events, including a timestamp and a unique identifier. It is abstract and implements the IEvent interface.", + "Roles": [ + "Base class for domain events", + "Implements IEvent interface" + ], + "Hash": "2F1A34D6CDA53CF9B71A6AE137D1403666B4831DE148669CB4CAD02ECE95F4EB" + } + }, + { + "Name": "ServiceCollectionExtensions.cs", + "Summary": { + "Summary": "Registers an event handler with a specified lifetime scope for handling events of type TEvent using the handler THandler. The method ensures the service collection is not null and registers the handler as a scoped service. The method returns the modified service collection for chaining purposes. The method is generic and requires TEvent to be a class implementing IEvent and THandler to be a class implementing IEventSubscriber\u003CTEvent\u003E.", + "Exceptions": "ArgumentNullException.ThrowIfNull(services);", + "Features": "AddEventHandler\u003CTEvent, THandler\u003E", + "Roles": [ + "fluentcms", + "infrastructure", + "eventbus" + ], + "Hash": "72A449092831131290EDD561D51C91BF73A94DE887F4E7833384429C75CE1285" + } + }, + { + "Name": "_GlobalUsings.cs", + "Summary": { + "Summary": "The file _GlobalUsings.cs contains two global usings: FluentCMS.Infrastructure.EventBus.Abstractions and Microsoft.Extensions.DependencyInjection. These usings are used to import namespaces for event bus abstractions and dependency injection services, respectively, to avoid repetitive using statements in the codebase.", + "Exceptions": "None", + "Features": "None", + "Roles": [ + "None" + ], + "Hash": "B9E192DFFC0ADF678F5295D86BEC639DD68C7572700CFE13CC7CC6D8D1142512" + } + }, + { + "Name": "FluentCMS.Infrastructure.EventBus.csproj", + "Summary": { + "Summary": "Project file for FluentCMS.Infrastructure.EventBus", + "Exceptions": "None", + "Features": "net10.0, ImplicitUsings enabled, Nullable enabled", + "Roles": [ + "Infrastructure", + "EventBus" + ], + "Hash": "CFC1700EA33F49C1A6FD1941F87B1FFED86EC1EBF39AD8FBDFF7D842D6DCC4AF" + } + } + ], + "Directories": [ + { + "Name": "Abstractions", + "Path": "src/EventBus/FluentCMS.Infrastructure.EventBus/Abstractions", + "FolderSummary": "The \u0022Abstractions\u0022 folder defines core interfaces for domain events, their publication, and subscription, enabling a decoupled event-driven architecture in the project.", + "Files": [ + { + "Name": "IEventSubscriber.cs", + "Summary": { + "Summary": "Generic event subscriber interface for handling domain events. Implement this interface to create event handlers that respond to specific event types.", + "Exceptions": "OperationCanceledException", + "Features": "Generic interface, asynchronous handling, cancellation support, thread safety considerations", + "Roles": [ + "Event Handler", + "Dependency Injection Registration" + ], + "Hash": "03E7F3AF8A5B254B090DEA82B5497C18DE4F01214F2B38CD28234A97DB632D69" + } + }, + { + "Name": "IEvent.cs", + "Summary": { + "Summary": "Marker interface for all domain events", + "Exceptions": "", + "Features": "This interface defines two properties: OccurredAt (DateTimeOffset) and EventId (Guid). Both are read-only.", + "Roles": [ + "Domain Events" + ], + "Hash": "17E7E53FD28EB31BF495679AEDD42523628E52D15E591896C26657F3C01DC2FA" + } + }, + { + "Name": "IEventPublisher.cs", + "Summary": { + "Summary": "Event publisher interface for publishing domain events", + "Exceptions": "None", + "Features": "Asynchronous event publishing", + "Roles": [ + "Domain event publisher" + ], + "Hash": "94D568E9947B5C68F8662FF74C1E58EA49F20ECB99536B7CDA6BAEC883414132" + } + } + ], + "Directories": [] + } + ] + } + ] + }, + { + "Name": "Common", + "Path": "src/Common", + "FolderSummary": "The \u0022Common\u0022 folder serves as a centralized repository for shared utilities, base classes, and infrastructure components within the FluentCMS project, including the FluentCMS.Infrastructure.Common subfolder that likely provides common service implementations or abstractions for the application\u0027s core functionality.", + "Files": [], + "Directories": [ + { + "Name": "FluentCMS.Infrastructure.Common", + "Path": "src/Common/FluentCMS.Infrastructure.Common", + "FolderSummary": "This folder in the FluentCMS foundational project provides shared infrastructure utilities, such as base entity classes (Entity and AuditableEntity), a user context interface (IUserContext), and global using declarations for common namespaces.", + "Files": [ + { + "Name": "FluentCMS.Infrastructure.Common.csproj", + "Summary": { + "Summary": "Project file for FluentCMS.Infrastructure.Common", + "Exceptions": "None", + "Features": "None", + "Roles": [ + "Project" + ], + "Hash": "2C82DAE7A6492E5DC0D99B6B5A5D1C89A4702B892F71757981E46302949D6115" + } + }, + { + "Name": "IUserContext.cs", + "Summary": { + "Summary": "Interface for user context in FluentCMS.", + "Exceptions": "", + "Features": "", + "Roles": [], + "Hash": "0092FC796DB4BE70B689F983DCCD1711371DA439C07E9D7F9CCFCB73A969B674" + } + }, + { + "Name": "Entity.cs", + "Summary": { + "Summary": "The Entity class and interface define a base entity with an Id property. The interface IEntity has a Key attribute on the Id property, and the Entity class implements this interface with a virtual Id property that defaults to a new Guid. This setup allows for a common base entity in the FluentCMS infrastructure, facilitating consistent entity handling across the application.", + "Exceptions": "None", + "Features": "None", + "Roles": [ + "None" + ], + "Hash": "024708C22B5A08D0AD0CDB3B0893A1F31C2089CA9CF600DB7143FADC753B2D81" + } + }, + { + "Name": "_GlobalUsings.cs", + "Summary": { + "Summary": "The file contains a global using directive for the System.ComponentModel.DataAnnotations namespace. This directive will make the namespace available globally across all files in the project, eliminating the need for individual using directives in each file.", + "Exceptions": "None", + "Features": "global using directive", + "Roles": [ + "global" + ], + "Hash": "A711FA1DCA70D4457591D9E8F07B57815067CAD9143B75FC1A27EEFC67807D83" + } + }, + { + "Name": "AuditableEntity.cs", + "Summary": { + "Summary": "AuditableEntity.cs contains an interface IAuditableEntity and an abstract class AuditableEntity. The interface extends IEntity and defines properties with concurrency checks and nullable fields. The abstract class implements the interface and provides virtual properties for each property in the interface. The namespace is FluentCMS.Infrastructure.", + "Exceptions": "none", + "Features": "none", + "Roles": [ + "none" + ], + "Hash": "106651FBC41C3FB5DAE95D91A194302E2E92806114A272082DA98318FA9775A3" + } + } + ], + "Directories": [] + } + ] + }, + { + "Name": "Providers", + "Path": "src/Providers", + "FolderSummary": "The Providers folder encapsulates implementations and abstractions for infrastructural services and data access layers in the FluentCMS project, including Entity Framework-based repositories.", + "Files": [], + "Directories": [ + { + "Name": "FluentCMS.Infrastructure.Providers", + "Path": "src/Providers/FluentCMS.Infrastructure.Providers", + "FolderSummary": "The FluentCMS.Infrastructure.Providers folder handles the discovery, caching, management, and configuration of provider modules, including dynamic loading from DLLs, feature management, and ensuring thread-safe access to active providers by area.", + "Files": [ + { + "Name": "ProviderModuleCatalogCache.cs", + "Summary": { + "Summary": "ProviderModuleCatalogCache manages a catalog of provider modules, using concurrent dictionaries for thread-safe operations. It validates modules for duplicates and proper properties, registers them by area and type, and provides methods for retrieval and lookup.", + "Exceptions": "duplicateModulesFoundInValidateModulesMethod", + "Features": "concurrentDictionary", + "Roles": [ + "ProviderModuleCatalogCache" + ], + "Hash": "3932464FE2DE4CE69A64CDB581E4BC6568A8F1B5D1E5895F67BBDF0B2C96EFFF" + } + }, + { + "Name": "ProviderFeatureBuilder.cs", + "Summary": { + "Summary": "The ProviderFeatureBuilder class is a sealed class within the FluentCMS.Infrastructure.Providers namespace. It is designed to hold an IServiceCollection instance, which is used for dependency injection configuration. The class has a public property named \u0027Services\u0027 of type IServiceCollection and an internal constructor that initializes this property with an IServiceCollection instance passed as a parameter.", + "Exceptions": "None", + "Features": "The class is sealed, preventing inheritance. It provides a public property for accessing the IServiceCollection instance and an internal constructor for initialization.", + "Roles": [ + "Dependency Injection Configuration", + "Provider Feature Management" + ], + "Hash": "D301066C7E6D6E8A52D7AC8774992870E82B56092EF6F27B899E2F08AB170E38" + } + }, + { + "Name": "ProviderManager.cs", + "Summary": { + "Summary": "ProviderManager class implements IProviderManager interface with two methods: GetProviderModule and GetActiveByArea. The class has a private async method Initialize which processes provider data from the repository, checks for multiple active providers in the same area, and initializes the providerCatalogCache. The GetProviderModule method returns a provider module from the providerModuleCatalogCache based on area and type name. The constructor takes three parameters: providerCatalogCache, providerModuleCatalogCache, and IProviderRepository. The Initialize method throws exceptions if a provider module is not found or if there are multiple active providers in the same area.", + "Exceptions": "ProviderManager class implements IProviderManager interface with two methods: GetProviderModule and GetActiveByArea. The class has a private async method Initialize which processes provider data from the repository, checks for multiple active providers in the same area, and initializes the providerCatalogCache. The GetProviderModule method returns a provider module from the providerModuleCatalogCache based on area and type name. The constructor takes three parameters: providerCatalogCache, providerModuleCatalogCache, and IProviderRepository. The Initialize method throws exceptions if a provider module is not found or if there are multiple active providers in the same area.", + "Features": "ProviderManager class implements IProviderManager interface with two methods: GetProviderModule and GetActiveByArea. The class has a private async method Initialize which processes provider data from the repository, checks for multiple active providers in the same area, and initializes the providerCatalogCache. The GetProviderModule method returns a provider module from the providerModuleCatalogCache based on area and type name. The constructor takes three parameters: providerCatalogCache, providerModuleCatalogCache, and IProviderRepository. The Initialize method throws exceptions if a provider module is not found or if there are multiple active providers in the same area.", + "Roles": [ + "ProviderManager class implements IProviderManager interface with two methods: GetProviderModule and GetActiveByArea. The class has a private async method Initialize which processes provider data from the repository, checks for multiple active providers in the same area, and initializes the providerCatalogCache. The GetProviderModule method returns a provider module from the providerModuleCatalogCache based on area and type name. The constructor takes three parameters: providerCatalogCache, providerModuleCatalogCache, and IProviderRepository. The Initialize method throws exceptions if a provider module is not found or if there are multiple active providers in the same area." + ], + "Hash": "BE0F8DD0125C92A42EC5FC47E420A28AEC2BFFF603A4B8353626C11A5F1485E8" + } + }, + { + "Name": "ProviderDiscovery.cs", + "Summary": { + "Summary": "The ProviderDiscovery class scans the executable directory for DLLs matching specified prefixes, loads them, and discovers provider modules by inspecting their types. It processes assemblies in parallel, ensuring thread safety and robust error handling.", + "Exceptions": "The code handles exceptions, but if IgnoreExceptions is false, it rethrows. The executable path is determined, and if it\u0027s null, an InvalidOperationException is thrown. The method uses a ConcurrentBag for thread-safe collection in parallel processing.", + "Features": "The code uses LINQ for filtering DLLs, Parallel.ForEach for processing in parallel, and ConcurrentBag for thread-safe collection. It handles ReflectionTypeLoadException to extract valid types.", + "Roles": [ + "The ProviderDiscovery class is responsible for discovering provider modules by scanning DLLs in the executable directory.", + "The GetProviderModules method returns a list of IProviderModule instances by loading and inspecting assemblies.", + "The method filters DLLs based on prefixes and processes them in parallel to improve performance.", + "The code ensures thread safety when adding provider modules to the collection.", + "The method handles exceptions during assembly loading and type extraction, providing flexibility based on the IgnoreExceptions flag.", + "The code uses Assembly.LoadFrom to load assemblies, which allows dynamic loading of DLLs.", + "The method checks if types are classes, non-abstract, and implement IProviderModule before creating instances.", + "The code uses a ConcurrentBag to safely collect provider modules across multiple threads.", + "The method returns a copy of the provider modules list to prevent external modification.", + "The code includes a try-catch block around the type processing to handle exceptions gracefully." + ], + "Hash": "B46914C3CDC56C104C784258DDEA1172CEE1AE0B392E9285520F1C94310710DC" + } + }, + { + "Name": "ProviderCatalogCache.cs", + "Summary": { + "Summary": "The ProviderCatalogCache class provides thread-safe caching for provider catalogs. It manages multiple catalogs by key and area, supports initialization, reloading, and clearing of the cache. The class ensures thread safety using locks and concurrent dictionaries.", + "Exceptions": "The class throws InvalidOperationException in scenarios such as adding catalogs after initialization or having multiple active providers for the same area.", + "Features": "Thread-safe caching using ConcurrentDictionary and lock, area-based and key-based catalog lookups, initialization and reloading mechanisms, and active catalog tracking.", + "Roles": [ + "Caching", + "Thread Safety", + "Provider Management" + ], + "Hash": "2466C5901049451CDA699638FBB112F57A8DEE18DEDE99C0090192DBA73B34EA" + } + }, + { + "Name": "_GlobalUsings.cs", + "Summary": { + "Summary": "This file defines global using directives for a C# project, importing namespaces related to FluentCMS infrastructure, Microsoft extensions, and system libraries to avoid repetitive using statements across the codebase.", + "Exceptions": "No unexpected elements; it consists solely of standard global using declarations.", + "Features": "Exports global using statements for various namespaces including infrastructure providers, repositories, configuration, dependency injection, and common system types.", + "Roles": [ + "Configuration" + ], + "Hash": "9C5995DDBFA470E5653C6F9A31FA1F0DE199D32710F52D9AD7E12388AA22C71E" + } + }, + { + "Name": "ProviderDiscoveryOptions.cs", + "Summary": { + "Summary": "This is a summary of the ProviderDiscoveryOptions class. It includes properties for enabling logging, specifying assembly prefixes to scan, and ignoring exceptions during the discovery process. The class is part of the FluentCMS.Infrastructure.Providers namespace.", + "Exceptions": "false", + "Features": "true", + "Roles": [ + "admin", + "user" + ], + "Hash": "2AA0B1B0BCFE5A359472590315FC1D67EB9983FE6E828DAC0C8F4126923C0DD8" + } + }, + { + "Name": "ProviderFeatureBuilderExtensions.cs", + "Summary": { + "Summary": "The ProviderFeatureBuilderExtensions class provides extension methods for configuring provider features in a .NET application. It includes methods for adding providers, using configuration, and preparing the provider catalog cache.", + "Exceptions": "The code handles exceptions during provider module configuration and instance creation, throwing detailed exceptions when exceptions are not ignored.", + "Features": "Key features include provider discovery, configuration, caching, and dependency injection setup for providers.", + "Roles": [ + "Developer", + "System Administrator" + ], + "Hash": "82834E912AC174E675970DBAC63B1A5B736865BF33AC87939EC1424E1BF7542F" + } + }, + { + "Name": "FluentCMS.Infrastructure.Providers.csproj", + "Summary": { + "Summary": "Project file for FluentCMS.Infrastructure.Providers", + "Exceptions": "None", + "Features": "None", + "Roles": [ + "Project" + ], + "Hash": "E454903A8CE50D0A9B5459E4CA25BD44DF8D8ED89753606DA52403E9E200D5FB" + } + }, + { + "Name": "ProviderCatalog.cs", + "Summary": { + "Summary": "ProviderCatalog class in FluentCMS Infrastructure.Providers namespace. It\u0027s a public class with a constructor that takes IProviderModule, string, bool, and object (optional). The class has four public read-only properties: Name, Active, Module, and Options, initialized from the constructor parameters.", + "Exceptions": "None", + "Features": "None", + "Roles": [ + "None" + ], + "Hash": "35B02F328840D4DE32FB5081931330181B490F97BF9457058F5CB087C096AB60" + } + } + ], + "Directories": [ + { + "Name": "Repositories", + "Path": "src/Providers/FluentCMS.Infrastructure.Providers/Repositories", + "FolderSummary": "The Repositories folder serves as an abstraction layer for data access in the project, containing provider implementations (like Provider.cs), abstract definitions, and configurations to manage interactions with data sources.", + "Files": [ + { + "Name": "Provider.cs", + "Summary": { + "Summary": "The Provider class represents a provider instance stored in the database. It includes properties for the provider\u0027s name, display name, area, module type, active status, and options. The class also includes validation attributes for each property to ensure data integrity.", + "Exceptions": "none", + "Features": "none", + "Roles": [ + "none" + ], + "Hash": "A62A6CDBCD2877BECD9976F7F96D66A0C6EEE008C422F65AA267695C54B1CDFE" + } + } + ], + "Directories": [ + { + "Name": "Abstractions", + "Path": "src/Providers/FluentCMS.Infrastructure.Providers/Repositories/Abstractions", + "FolderSummary": "The \u0022Abstractions\u0022 folder holds interface definitions, such as IProviderRepository, to establish contracts for services and repositories, enabling dependency injection and improved modularity in the project.", + "Files": [ + { + "Name": "IProviderRepository.cs", + "Summary": { + "Summary": "The IProviderRepository interface is defined in the FluentCMS.Infrastructure.Providers.Repositories.Abstractions namespace. It extends the IRepository\u003CProvider\u003E interface, indicating it is part of a repository pattern for Provider entities. The interface itself contains no additional methods or properties beyond the inheritance from IRepository.", + "Exceptions": "None", + "Features": "None", + "Roles": [ + "None" + ], + "Hash": "24D34A62DF4256EE4C6E8A284B088D803D655FEE7436ABFACC206BED3BBB7E95" + } + } + ], + "Directories": [] + }, + { + "Name": "Configuration", + "Path": "src/Providers/FluentCMS.Infrastructure.Providers/Repositories/Configuration", + "FolderSummary": "This folder handles configuration management by providing interfaces and implementations for read-only provider repositories and generic in-memory query specifications used to access and query configuration data.", + "Files": [ + { + "Name": "ConfigurationReadOnlyProviderRepository.cs", + "Summary": { + "Summary": "This class provides read-only access to provider configurations from an in-memory repository. It retrieves provider data from the configuration file and uses the provider manager to get module details. The repository does not support any write operations, as indicated by the NotImplementedException in all write-related methods. The internal ProviderAreaConfiguration class is used to deserialize provider area configurations from the configuration file. The GetAll method processes each provider area and module, serializing options if necessary. The Query method returns an in-memory query specification based on the retrieved providers.", + "Exceptions": "NotImplementedException", + "Features": "In-memory repository", + "Roles": [ + "IProviderRepository" + ], + "Hash": "28DD40B51123CDEF47546D969257CBBCD2C49CA208765F9B25D9F28BFAE27A17" + } + }, + { + "Name": "InMemoryQuerySpecification.cs", + "Summary": { + "Summary": "InMemoryQuerySpecification\u003CT\u003E is a class that provides in-memory query operations for a collection of T objects. It supports various query methods like filtering, ordering, grouping, and pagination, with cancellation token support and async enumeration capabilities.", + "Exceptions": "No exceptionsthrown in the provided code.", + "Features": "The code defines a class InMemoryQuerySpecification\u003CT\u003E that implements IQuerySpecification\u003CT\u003E. It provides methods for querying in-memory collections, including Any, Count, AsAsyncEnumerable, Distinct, First, Single, Skip, Take, OrderBy, ThenBy, GroupBy, Select, ToArray, ToList, and ToPagedResult. The class uses a constructor that takes an IEnumerable\u003CT\u003E and stores it internally. The methods handle cancellation tokens and compile expressions. The GetAsyncEnumerable method uses yield return and Task.Yield for async enumeration with cancellation support.", + "Roles": [ + "Class", + "Generic", + "Implements IQuerySpecification\u003CT\u003E", + "Uses IEnumerable\u003CT\u003E as parameter and storage" + ], + "Hash": "1A1E3679CEECD3ABBD3F68252ACA9B2AF27D9BCAF7752EB82FA769FE1803B817" + } + } + ], + "Directories": [] + } + ] + } + ] + }, + { + "Name": "FluentCMS.Infrastructure.Providers.Abstractions", + "Path": "src/Providers/FluentCMS.Infrastructure.Providers.Abstractions", + "FolderSummary": "The FluentCMS Infrastructure Providers Abstractions folder defines fundamental interfaces and base classes, such as IProvider and ProviderModuleBase, to establish contracts and shared functionality for provider modules within the system\u0027s provider architecture.", + "Files": [ + { + "Name": "IProviderModule.cs", + "Summary": { + "Summary": "The code defines interfaces for provider modules in a .NET application. The base interface IProviderModule provides common properties and a method for configuring services. The generic interfaces IProviderModule\u003CTProvider, TOptions\u003E and IProviderModule\u003CTProvider\u003E allow for strongly-typed implementations with constraints on the provider and options types. These interfaces facilitate the creation of provider modules with specific types and configurations.", + "Exceptions": "The code file defines two interfaces: IProviderModule and two generic versions of it. The base interface IProviderModule has properties like Area, DisplayName, ProviderType, OptionsType, InterfaceType, and a ConfigureServices method. The generic interfaces IProviderModule\u003CTProvider, TOptions\u003E and IProviderModule\u003CTProvider\u003E inherit from IProviderModule and add type parameters with constraints. The constraints specify that TProvider must be a class implementing IProvider, and TOptions must be a class with a parameterless constructor.", + "Features": "The code defines a base interface for provider modules with properties and a configuration method. It also provides two generic interfaces for strongly-typed provider modules with specific type constraints. The generic interfaces allow for more specific implementations by constraining the provider and options types.", + "Roles": [ + "Developer", + "Architect", + "Maintainer" + ], + "Hash": "BA5EC816488EE208CB46E6B67C4B1563C7E5F6F0D145A1E781DB21B2B0696051" + } + }, + { + "Name": "FluentCMS.Infrastructure.Providers.Abstractions.csproj", + "Summary": { + "Summary": "Project file for FluentCMS.Infrastructure.Providers.Abstractions, targeting .NET 10.0 with implicit usings enabled and nullable reference types enabled. It references Microsoft.Extensions.DependencyInjection.Abstractions version 10.0.2.", + "Exceptions": "None", + "Features": "None", + "Roles": [ + "None" + ], + "Hash": "FC04C4B5AE787E8C3250DF3CDC84F4DDECB3C2EB7E6E83D3D5B149C3767B817F" + } + }, + { + "Name": "IProvider.cs", + "Summary": { + "Summary": "Base marker interface for all providers. All provider implementations must implement this interface.", + "Exceptions": "", + "Features": "This interface serves as a base marker for all provider implementations in the FluentCMS infrastructure. It is located in the FluentCMS.Infrastructure.Providers.Abstractions namespace.", + "Roles": [ + "Base marker interface" + ], + "Hash": "7B8D0585F3DDC7FDE0E89BD00CDAD68463475E2BAF14D45B679B794224F7FDCC" + } + }, + { + "Name": "ProviderModuleBase.cs", + "Summary": { + "Summary": "ProviderModuleBase.cs", + "Exceptions": "ProviderModuleBase.cs", + "Features": "ProviderModuleBase.cs", + "Roles": [ + "ProviderModuleBase\u003CTProvider, TOptions\u003E", + "ProviderModuleBase\u003CTProvider\u003E" + ], + "Hash": "C0815D03769D080A254EBFDDC0225C3D15C15E0561776E75273B2858DDF4771A" + } + } + ], + "Directories": [] + }, + { + "Name": "FluentCMS.Infrastructure.Providers.Repositories.EntityFramework", + "Path": "src/Providers/FluentCMS.Infrastructure.Providers.Repositories.EntityFramework", + "FolderSummary": "This folder implements the Entity Framework-based repository and database infrastructure for managing provider-related data in FluentCMS, including schema validation, seeding, context handling, and feature extensions.", + "Files": [ + { + "Name": "ProviderSchemaValidator.cs", + "Summary": { + "Summary": "ProviderSchemaValidator class in FluentCMS Infrastructure.Providers.Repositories.EntityFramework namespace", + "Exceptions": "None", + "Features": "Inherits from BaseSchemaValidator\u003CProviderDbContext\u003E, overrides Priority property with value 1", + "Roles": [ + "ProviderSchemaValidator" + ], + "Hash": "8209FB9BFD2CC50C33CAC6FB2FA685FFDE9DD69AAF9FD7188B8A842243D9D67C" + } + }, + { + "Name": "ProviderDbContext.cs", + "Summary": { + "Summary": "Entity Framework database context for the provider system. It includes a DbSet for Provider entities and configures the Provider entity in the OnModelCreating method. The Provider entity has properties like Id (primary key), Name, DisplayName, Area, ModuleType, Options (supporting JSON with Unicode), and IsActive (default false). The model configuration enforces required fields with specific length constraints and sets default values where applicable.", + "Exceptions": "None", + "Features": "None", + "Roles": [ + "None" + ], + "Hash": "D54D1870788C92E076D30F3F457F9538142C9217ED1E95D3EC48E4E789712BCB" + } + }, + { + "Name": "ProviderDataSeeder.cs", + "Summary": { + "Summary": "ProviderDataSeeder class in FluentCMS infrastructure for seeding provider data using Entity Framework.", + "Exceptions": "InvalidOperationException if provider module not found.", + "Features": "Uses dependency injection, async operations, and Entity Framework\u0027s AddRangeAsync and SaveChangesAsync.", + "Roles": [ + "ProviderDataSeeder", + "BaseDataSeeder\u003CProviderDbContext\u003E" + ], + "Hash": "5EB767CF852A7E70A64B351879BE00CCB3D1AC64358B3B84B614EA816F3CF0B1" + } + }, + { + "Name": "IProviderDatabaseMarker.cs", + "Summary": { + "Summary": "IProviderDatabaseMarker is an empty interface that inherits from IDatabaseArea.", + "Exceptions": "", + "Features": "", + "Roles": [ + "interface" + ], + "Hash": "8B3813BB876C15C2C25C4AAD7EFC3B5D5941EA4947747ECF3DE551C748D20385" + } + }, + { + "Name": "ProviderRepository.cs", + "Summary": { + "Summary": "ProviderRepository class in the FluentCMS infrastructure providers repository namespace, implementing IProviderRepository and inheriting from Repository\u003CProvider, ProviderDbContext\u003E with a constructor that injects ProviderDbContext.", + "Exceptions": "None", + "Features": "Implements IProviderRepository, inherits from Repository\u003CProvider, ProviderDbContext\u003E, constructor injects ProviderDbContext.", + "Roles": [ + "Repository", + "Entity Framework Provider Repository" + ], + "Hash": "E8B0861B51ACBFB030EF04942DCA45169A3BFEC560C19BB8E79F55F6BEECB409" + } + }, + { + "Name": "_GlobalUsings.cs", + "Summary": { + "Summary": "Global Usings Directives", + "Exceptions": "None", + "Features": "None", + "Roles": [ + "None" + ], + "Hash": "F7BD14B5061145750B9A21B19E8403854939255E5CB82ED648AAB05C74F6920E" + } + }, + { + "Name": "FluentCMS.Infrastructure.Providers.Repositories.EntityFramework.csproj", + "Summary": { + "Summary": "Project file for FluentCMS.Infrastructure.Providers.Repositories.EntityFramework", + "Exceptions": "None", + "Features": "None", + "Roles": [ + "Project" + ], + "Hash": "54D65E6CB645D1947B0F833E05E09A2228899C15F1ED87CF15E33AF59369CD49" + } + }, + { + "Name": "ProviderFeatureBuilderExtensions.cs", + "Summary": { + "Summary": "The \u0060ProviderFeatureBuilderExtensions\u0060 class provides an extension method to configure Entity Framework integration in a FluentCMS provider feature builder. It adds necessary repositories, data seeder, schema validator, database context, and repository implementation services.", + "Exceptions": "The JSON output must be valid. The provided code analysis is correct and does not contain any exceptions. The JSON structure is valid and accurately represents the code\u0027s components and their relationships.", + "Features": "The code defines a static class \u0060ProviderFeatureBuilderExtensions\u0060 within the \u0060FluentCMS.Infrastructure.Providers.Repositories.EntityFramework\u0060 namespace. The class contains a single extension method \u0060UseEntityFramework\u0060 that configures Entity Framework services for a \u0060ProviderFeatureBuilder\u0060 instance. The method adds several scoped services, including \u0060ConfigurationReadOnlyProviderRepository\u0060, \u0060ProviderDataSeeder\u0060, \u0060ProviderSchemaValidator\u0060, \u0060ProviderDbContext\u0060, and \u0060IProviderRepository\u0060 (implemented by \u0060ProviderRepository\u0060). The method returns the modified \u0060ProviderFeatureBuilder\u0060.", + "Roles": [ + "Developer", + "Analyst" + ], + "Hash": "E8E53C8EF6EFB02FE32708056121FAA74E4ED3686ACB2B921AB1FCCF3897E74F" + } + } + ], + "Directories": [] + } + ] + }, + { + "Name": "Configuration", + "Path": "src/Configuration", + "FolderSummary": "The Configuration folder contains infrastructure-level settings and Entity Framework configurations for the FluentCMS project, supporting different database providers such as SQL Server and SQLite.", + "Files": [], + "Directories": [ + { + "Name": "FluentCMS.Infrastructure.Configuration.EntityFramework.SqlServer", + "Path": "src/Configuration/FluentCMS.Infrastructure.Configuration.EntityFramework.SqlServer", + "FolderSummary": "This folder is responsible for providing configuration and extension methods to integrate Entity Framework ORM with SQL Server as the database provider in the FluentCMS project infrastructure.", + "Files": [ + { + "Name": "FluentCMS.Infrastructure.Configuration.EntityFramework.SqlServer.csproj", + "Summary": { + "Summary": "Project file for FluentCMS Infrastructure Configuration Entity Framework with SQL Server", + "Exceptions": "None", + "Features": "None", + "Roles": [ + "ProjectFile", + "Csproj" + ], + "Hash": "4E33ED76983284D0FF2BDA250BD1264973D09905A18707B87FF04C954A5A964B" + } + }, + { + "Name": "ConfigurationExtensions.cs", + "Summary": { + "Summary": "Extension methods for adding database configuration with SQL Server", + "Exceptions": "", + "Features": "This class provides extension methods to add SQL Server database configuration to an IConfigurationBuilder. It uses a temporary configuration manager to create a DbContextOptionsBuilder for SQL Server, then adds the database configuration provider. The method allows specifying a connection string and an optional reload interval for automatic updates.", + "Roles": [], + "Hash": "2A665CFB7B8CBC907BD96027A191C116FA79DFBD723243AB7464DEDBF6785F51" + } + } + ], + "Directories": [] + }, + { + "Name": "FluentCMS.Infrastructure.Configuration.EntityFramework", + "Path": "src/Configuration/FluentCMS.Infrastructure.Configuration.EntityFramework", + "FolderSummary": "This folder handles the Entity Framework-based infrastructure for managing and retrieving configuration data in FluentCMS, including database contexts, repositories, seeding, validation, and providers.", + "Files": [ + { + "Name": "InMemoryCache.cs", + "Summary": { + "Summary": "Simple in-memory cache for configuration values", + "Exceptions": "None", + "Features": "ConcurrentDictionary, DateTime, TimeSpan, required keyword", + "Roles": [ + "internal" + ], + "Hash": "7462A09FA39652656FB5467E26B91348322E85923E7851B5E8E37E6ACA753D08" + } + }, + { + "Name": "ConfigurationDataSeeder.cs", + "Summary": { + "Summary": "The ConfigurationDataSeeder class is responsible for seeding configuration data into the database. It inherits from BaseDataSeeder and has the lowest priority (0) to ensure it runs last. The class processes registered configuration sections, checks for existing entries, and seeds new ones by converting sections to JSON and storing them in the database. It includes error handling for missing or empty sections and logs actions accordingly. The class uses a recursive method to convert configuration sections into dictionaries for serialization.", + "Exceptions": "None", + "Features": "ConfigurationDataSeeder class", + "Roles": [ + "ConfigurationDataSeeder" + ], + "Hash": "ED39387F08C78045406A3E99E08D46FE8768EEF632765B6F135B9C5410AD9378" + } + }, + { + "Name": "FluentCMS.Infrastructure.Configuration.EntityFramework.csproj", + "Summary": { + "Summary": "none", + "Exceptions": "none", + "Features": "none", + "Roles": [ + "none" + ], + "Hash": "A9522B74628928EC605909C76C812345DF60FC6AD313166BE17DB16CD588CB9B" + } + }, + { + "Name": "ConfigurationDbContext.cs", + "Summary": { + "Summary": "DbContext for storing configuration data in FluentCMS infrastructure using Entity Framework. It defines a DbSet for ConfigurationEntity and configures the entity model with required fields, unique index on Section, and other constraints. The class inherits from DbContext and uses a constructor with DbContextOptions parameter. The OnModelCreating method overrides base method to configure the entity properties including Id as primary key, Section, Value, Type, CreatedAt, and Version with specific attributes like IsRequired, MaxLength, and IsUnique index. The ConfigurationEntity class is referenced but not defined in this file, indicating it\u0027s part of the same namespace or assembly. The model configuration ensures data integrity through unique constraints and required fields. The DbContext is part of the FluentCMS infrastructure, specifically under the Configuration.EntityFramework namespace, suggesting it\u0027s used for managing configuration settings in the application\u0027s backend. The code follows standard Entity Framework practices for DbContext and model configuration, with proper use of attributes and methods to define the database schema. The unique index on Section helps prevent duplicate configuration sections, which is important for maintaining data consistency in configuration management. The required fields ensure that critical data like Value and Type are always present when creating or updating configuration entities. The CreatedAt and Version fields likely track when the configuration was created and its version for audit and update purposes. The DbContext class is designed to be used in a dependency injection container, as is common in ASP.NET Core applications, to provide the configuration data layer. The code is well-structured and follows best practices for Entity Framework Core DbContext implementation, including proper model configuration and error handling through the base class methods. The absence of any exception handling in the provided code snippet suggests that it\u0027s a simplified version, and in a production environment, additional error handling might be necessary. The code is part of a larger system, and the ConfigurationEntity class would define the actual properties and relationships for the configuration data, which is not shown here. The unique index on Section implies that each configuration section must have a unique name, which is a common requirement for configuration systems to avoid conflicts. The required fields for Value and Type ensure that these critical pieces of information are always provided, which is essential for the application to function correctly with the configuration data. The CreatedAt field likely uses a DateTime type to record when the configuration was created, which is useful for auditing and tracking changes over time. The Version field might be used to manage different versions of the configuration, allowing for updates and rollbacks if needed. The DbContext class is designed to be flexible and reusable, as it inherits from DbContext and allows for customization through the DbContextOptions parameter. This makes it easy to integrate with different database providers or configurations in the application. The model configuration in OnModelCreating is a key part of the DbContext, as it defines how the entity maps to the database schema, including primary keys, indexes, and property constraints. This ensures that the database schema is correctly set up to support the application\u0027s configuration needs. The code is well-documented with XML comments, which is a good practice for maintainability and understanding the purpose of each part of the code. The comments describe the class, its constructor, and the purpose of the DbSet and OnModelCreating method, which helps other developers understand the code more easily. The use of the base class method in OnModelCreating ensures that any base class configurations are preserved, which is important for maintaining the integrity of the DbContext\u0027s behavior. Overall, the code is a well-written and properly structured part of the FluentCMS infrastructure, providing a solid foundation for managing configuration data in the application.", + "Exceptions": "None", + "Features": "ConfigurationDbContext class", + "Roles": [ + "Infrastructure", + "Configuration", + "EntityFramework" + ], + "Hash": "C3BA2B5DD49D067708CF97A3A242986A41655A42CCF043473CED145CA744D7E1" + } + }, + { + "Name": "ConfigurationRepository.cs", + "Summary": { + "Summary": "The ConfigurationRepository class is part of the FluentCMS Infrastructure Configuration Entity Framework module. It is designed to handle configuration entities using the Repository pattern and the Entity Framework DbContext.", + "Exceptions": "No exceptions were thrown during the analysis of the code file.", + "Features": "The code file contains a class named ConfigurationRepository that inherits from a Repository class and implements the IConfigurationRepository interface. The class has a constructor that takes a ConfigurationDbContext parameter.", + "Roles": [ + "analyst", + "developer", + "tester" + ], + "Hash": "772A75DC699FA83FFD09D915E6355918AC1213A5F175FC6AEFB632FDF4C9F56F" + } + }, + { + "Name": "DatabaseConfigurationExtensions.cs", + "Summary": { + "Summary": "This class contains extension methods for adding database configuration to the configuration system in a .NET application. It supports automatic discovery of database options and provides a way to manage configuration settings through a database context. The methods facilitate the setup of database configuration providers, service registration, and temporary configuration management for development and testing scenarios.", + "Exceptions": "None", + "Features": "The DatabaseConfigurationExtensions class provides extension methods for configuring database settings in a .NET application. It includes methods to add database configuration to the configuration builder, register services for database configuration, and create a temporary configuration manager for quick setup.", + "Roles": [ + "Developer", + "Database Administrator" + ], + "Hash": "8538C7E2087C25E20FBF257E593A88DAFB70762801F208D0E7FC7B84D3E67BF4" + } + }, + { + "Name": "_GlobalUsings.cs", + "Summary": { + "Summary": "None", + "Exceptions": "None", + "Features": "None", + "Roles": [ + "None" + ], + "Hash": "092B9E616C4965D1EAD64E1FB31D194475CA9C675D5B4A65FC4A3F3CD1B7F55B" + } + }, + { + "Name": "ConfigurationSchemaValidator.cs", + "Summary": { + "Summary": "The configuration schema validator has the lowest priority to ensure it runs last", + "Exceptions": "ConfigurationSchemaValidator.cs", + "Features": "internal class ConfigurationSchemaValidator(ConfigurationDbContext dbContext, ILogger\u003CConfigurationSchemaValidator\u003E logger) : BaseSchemaValidator\u003CConfigurationDbContext\u003E(dbContext, logger)", + "Roles": [ + "internal", + "class", + "ConfigurationSchemaValidator", + "ConfigurationDbContext", + "ILogger\u003CConfigurationSchemaValidator\u003E", + "BaseSchemaValidator\u003CConfigurationDbContext\u003E", + "override", + "int", + "Priority", + "0" + ], + "Hash": "05E3B961E87D151D7EC66BB7EBB5F18020B80BBDB4130F9A861E20E2A008CE53" + } + }, + { + "Name": "DatabaseConfigurationProvider.cs", + "Summary": { + "Summary": "This class implements a custom configuration provider that loads configuration settings from a database using Entity Framework Core, including in-memory caching, automatic periodic reloading, and conversion of nested JSON configurations into flat key-value pairs for use in .NET configuration systems.", + "Exceptions": "The file handles JsonException by skipping configurations with invalid JSON parsing, and ignores all exceptions during reload operations to prevent failures.", + "Features": "Database-backed configuration loading, in-memory caching using a custom InMemoryCache, automatic periodic reloading with a timer, flattening of JSON objects and arrays into dotted notation keys, change detection for triggering reload events, and proper disposal of resources including the timer.", + "Roles": [ + "ConfigurationProvider" + ], + "Hash": "4EE8D427E76518663F44FC9FEA0BDF9FE67CEFA2867E731F395F30DBFCD63DB4" + } + }, + { + "Name": "DatabaseConfigurationSource.cs", + "Summary": { + "Summary": "Configuration source for database-backed configurations. It uses a DbContextOptions to connect to the database and a ReloadInterval to determine how often the configuration should be refreshed from the database. The Build method creates a DatabaseConfigurationProvider instance with the provided options and interval.", + "Exceptions": "The DbOptions property is set to null, which may cause issues when building the DatabaseConfigurationProvider. This should be initialized with a valid DbContextOptions instance.", + "Features": "The DatabaseConfigurationSource implements IConfigurationSource and provides a way to build a DatabaseConfigurationProvider for database-backed configurations. The ReloadInterval property allows for periodic updates of the configuration from the database.", + "Roles": [ + "IConfigurationSource" + ], + "Hash": "A9D97851C25ED3AAE94C0C8F42B1A4607ED1CEF36C83B65C999754B9314E88A1" + } + } + ], + "Directories": [] + }, + { + "Name": "FluentCMS.Infrastructure.Configuration.EntityFramework.Sqlite", + "Path": "src/Configuration/FluentCMS.Infrastructure.Configuration.EntityFramework.Sqlite", + "FolderSummary": "This folder handles the infrastructure-level configuration and extensions for integrating SQLite as a database provider using Entity Framework in the FluentCMS project.", + "Files": [ + { + "Name": "FluentCMS.Infrastructure.Configuration.EntityFramework.Sqlite.csproj", + "Summary": { + "Summary": "Project file for FluentCMS.Infrastructure.Configuration.EntityFramework.Sqlite.csproj. Contains references to other projects and configuration settings.", + "Exceptions": "None", + "Features": "None", + "Roles": [ + "None" + ], + "Hash": "7292A94E83CE9D6B62745F19AAEDC059CE6486D11B210BB6D6FCA341F6E4383E" + } + }, + { + "Name": "ConfigurationExtensions.cs", + "Summary": { + "Summary": "This file defines extension methods for the configuration builder to integrate SQLite as a database provider for application configuration using Entity Framework.", + "Exceptions": "Throws an InvalidOperationException if the specified connection string is not found in the temporary configuration.", + "Features": "Provides an extension method AddSqliteConfiguration that sets up SQLite database for configuration storage, retrieves connection string, and adds database configuration with optional reload interval.", + "Roles": [ + "Extension", + "Configurator" + ], + "Hash": "1F6E6CD45CA6610AA7CEEBA5EFC2F9F5703B7769D9C64FB67A9C17BEB1A2700C" + } + } + ], + "Directories": [] + }, + { + "Name": "FluentCMS.Infrastructure.Configuration", + "Path": "src/Configuration/FluentCMS.Infrastructure.Configuration", + "FolderSummary": "The FluentCMS.Infrastructure.Configuration folder is responsible for managing system-level configuration infrastructure, including database setup, configuration entities, extensions for database operations, and abstractions for configurable components within the FluentCMS project.", + "Files": [ + { + "Name": "ConfigurationEntity.cs", + "Summary": { + "Summary": "Represents a configuration entry stored in the database. The class includes properties for the configuration section, JSON serialized value, and the full type name of the configuration object. It inherits from AuditableEntity, which likely includes audit fields like CreatedBy and UpdatedBy. The properties are all required strings, ensuring that each configuration entry has a section name, a JSON value, and a type name for deserialization purposes. This design allows the system to store and retrieve configuration settings dynamically by their section and type, facilitating flexible configuration management in the application.", + "Exceptions": "ConfigurationEntity.cs", + "Features": "ConfigurationEntity.cs", + "Roles": [ + "ConfigurationEntity.cs" + ], + "Hash": "0E963A7C57F533DA349D3C41F4BDA52CF2730A101E87F0B2163B573A26276595" + } + }, + { + "Name": "DatabaseConfigurationExtensions.cs", + "Summary": { + "Summary": "Static extension methods for adding database-backed configuration options to ASP.NET Core applications, integrating with the Options pattern and DatabaseConfigurationRegistry for section registration and binding.", + "Exceptions": "ArgumentNullException.ThrowIfNull", + "Features": "thread-safe registry creation, multi-tenant scenarios, database-backed configuration options", + "Roles": [ + "developer", + "architect" + ], + "Hash": "A377BF8E3CBC122B8011C881193D86953B2A616D9949F9D2F647F722EFC818DF" + } + }, + { + "Name": "FluentCMS.Infrastructure.Configuration.csproj", + "Summary": { + "Summary": "None", + "Exceptions": "None", + "Features": "None", + "Roles": [ + "None" + ], + "Hash": "71055E15B1BEAA2F8432A6CC5F353AE25500FDFBC0E5AE76B4AD66BC5E33644C" + } + }, + { + "Name": "_GlobalUsings.cs", + "Summary": { + "Summary": "This C# file defines global using directives, making specified namespaces available throughout the project without explicit imports in each file.", + "Exceptions": "None; the file contains only standard global using statements for namespaces related to dependency injection, configuration, options, and collections.", + "Features": "Provides global access to namespaces including FluentCMS custom repositories, Microsoft extensions for configuration and dependency injection, options handling, and concurrent collections.", + "Roles": [ + "Configuration", + "Utility" + ], + "Hash": "9AD833044262FC90232FC8261BE5733B36C5F1FC05EFD04CDF730CA5F412DD75" + } + }, + { + "Name": "DatabaseConfigurationRegistry.cs", + "Summary": { + "Summary": "DatabaseConfigurationRegistry is a singleton class that tracks configuration sections stored in the database. It ensures section names follow best practices and validates options types for the Options pattern. The registry is thread-safe and provides defensive copies of registered sections.", + "Exceptions": "invalid_section_name_length", + "Features": "concurrent_dictionary", + "Roles": [ + "configuration_registry", + "options_validator" + ], + "Hash": "1B0CE469834D678E0A0C10DBCA813BEC10C8646327EEE26FBBA073349BF3B3EA" + } + } + ], + "Directories": [ + { + "Name": "Abstractions", + "Path": "src/Configuration/FluentCMS.Infrastructure.Configuration/Abstractions", + "FolderSummary": "The Abstractions folder contains interface definitions for configuration repositories and database markers, facilitating dependency injection and abstraction of configuration-related data access in the project.", + "Files": [ + { + "Name": "IConfigurationRepository.cs", + "Summary": { + "Summary": "IConfigurationRepository interface in FluentCMS.Infrastructure.Configuration.Abstractions namespace", + "Exceptions": "None", + "Features": "Inherits from IRepository\u003CConfigurationEntity\u003E", + "Roles": [ + "ConfigurationRepository" + ], + "Hash": "C82FB26E097C02C1F68FFFD905E87CCF4C87FF24E9D08DE29287E404EE8BB807" + } + }, + { + "Name": "IConfigurationDatabaseMarker.cs", + "Summary": { + "Summary": "This interface is a marker interface for configuration database area. It inherits from IDatabaseArea interface.", + "Exceptions": "None", + "Features": "None", + "Roles": [ + "None" + ], + "Hash": "B72526F877D2F42A7CA35B69A6739FA14FD5F1C8D128762B269337898B5F9EAA" + } + } + ], + "Directories": [] + } + ] + } + ] + }, + { + "Name": "Repositories", + "Path": "src/Repositories", + "FolderSummary": "This folder houses the data access layer implementations for FluentCMS, providing Entity Framework-based repositories for database operations across different SQL providers like SQLite and SQL Server.", + "Files": [], + "Directories": [ + { + "Name": "FluentCMS.Infrastructure.Repositories.EntityFramework.Sqlite", + "Path": "src/Repositories/FluentCMS.Infrastructure.Repositories.EntityFramework.Sqlite", + "FolderSummary": "This folder handles SQLite database configuration and extensions for Entity Framework repositories within the FluentCMS infrastructure.", + "Files": [ + { + "Name": "FluentCMS.Infrastructure.Repositories.EntityFramework.Sqlite.csproj", + "Summary": { + "Summary": "Project file for FluentCMS.Infrastructure.Repositories.EntityFramework.Sqlite", + "Exceptions": "None", + "Features": "None", + "Roles": [ + "ProjectFile" + ], + "Hash": "EB470FD122C5EF59813EEE283B1C80E5EA8BAB067BE679546EF216EFAF213DC4" + } + }, + { + "Name": "SqliteConfigurationExtensions.cs", + "Summary": { + "Summary": "Extension methods for configuring SQLite database provider", + "Exceptions": "DatabaseConfigurationBuilder", + "Features": "SqliteDbContextOptionsBuilder", + "Roles": [ + "fluent", + "configuration", + "sqlite" + ], + "Hash": "185DBB2D2C665F313F2C846E718391CB50409DC87894DFABA165533ABB4D607F" + } + } + ], + "Directories": [] + }, + { + "Name": "FluentCMS.Infrastructure.Repositories", + "Path": "src/Repositories/FluentCMS.Infrastructure.Repositories", + "FolderSummary": "This folder handles the infrastructure layer\u0027s repository components in the FluentCMS project, encompassing data access abstractions, database initialization conditions, pagination utilities, seeding options, schema validation, and domain events for entity operations.", + "Files": [ + { + "Name": "ConfigurationCondition.cs", + "Summary": { + "Summary": "Condition that checks configuration settings to determine if seeding should execute. Compares a configuration value against an expected value using case-insensitive comparison.", + "Exceptions": "OperationCanceledException", + "Features": "ConfigurationCondition", + "Roles": [ + "IDbInitializationCondition" + ], + "Hash": "42C0169BE686A75689DD6CCCA305182667CE21220F9736F9611F041BE02937DC" + } + }, + { + "Name": "CompositeCondition.cs", + "Summary": { + "Summary": "Condition that combines multiple conditions with AND/OR logic. This allows for complex conditional logic by composing simpler conditions.", + "Exceptions": "ArgumentNullException when conditions is null", + "Features": "Parallel execution of conditions, error handling with detailed condition names, empty condition returns true", + "Roles": [ + "IDbInitializationCondition" + ], + "Hash": "82959B440869CD6D0409650274B7F829213B4A50B862DE4497C99E3ED3ADDFA7" + } + }, + { + "Name": "EnvironmentCondition.cs", + "Summary": { + "Summary": "Condition that checks the current hosting environment against a custom predicate. This allows for flexible environment-based seeding logic, such as seeding specific data only in Development, Staging, or Production environments.", + "Exceptions": "ArgumentException, Exception", + "Features": "EnvironmentCondition, IDbInitializationCondition", + "Roles": [ + "constructor", + "property", + "method" + ], + "Hash": "D0FA5480AC0C5999DEB074F9DE5E9FDC5A44C81DF1AA2B25BA503EE50F1F0F78" + } + }, + { + "Name": "PagedResult.cs", + "Summary": { + "Summary": "The PagedResult class implements pagination result wrapper functionality. It provides properties for items, total count, current page, and page size. It also includes computed properties for total pages, next page availability, and previous page availability. The class is generic and implements the IPagedResult interface. It uses C# 9.0 init properties and Math.Ceiling for calculations. The class is part of the FluentCMS.Infrastructure.Repositories namespace.", + "Exceptions": "None", + "Features": "None", + "Roles": [ + "Developer", + "Analyst" + ], + "Hash": "99D55AC96BF5E108D158BA37F46B81E6EDED07E1271214408D7ADBEA1F802640" + } + }, + { + "Name": "DataSeedingOptions.cs", + "Summary": { + "Summary": "Configuration options for the database seeding process", + "Exceptions": "ignore", + "Features": "seed", + "Roles": [ + "admin", + "user" + ], + "Hash": "45FDA85E507B99360D0AA8325628BFFE21891A7FA53B1B816AE66B64F830FD61" + } + }, + { + "Name": "_GlobalUsings.cs", + "Summary": { + "Summary": "This file contains global using directives for FluentCMS infrastructure, Microsoft.Extensions, and System.Linq.Expressions.", + "Exceptions": ",", + "Features": ",", + "Roles": [ + "Developer" + ], + "Hash": "D3C37C66CF42CC95A6C04B4FB4728B6DC68B807892BA6F64CF990FB1D2C8A317" + } + }, + { + "Name": "SchemaValidationOptions.cs", + "Summary": { + "Summary": "SchemaValidationOptions class defines configuration options for the schema validation process in FluentCMS. It includes a list of conditions that must be met before seeding and a flag to ignore exceptions during seeding.", + "Exceptions": "The class has two public properties: Conditions (List\u003CIDbInitializationCondition\u003E) and IgnoreExceptions (bool). The Conditions property is initialized as an empty list, and IgnoreExceptions defaults to false.", + "Features": "Key features include the ability to specify pre-seeding conditions and control exception handling during the seeding process.", + "Roles": [ + "Infrastructure Repositories" + ], + "Hash": "987EA41FFE3989C7DB92BEF6B9D1133587639C7770F0FBC45BCE99B2C9D1C47A" + } + }, + { + "Name": "FluentCMS.Infrastructure.Repositories.csproj", + "Summary": { + "Summary": "None", + "Exceptions": "None", + "Features": "None", + "Roles": [ + "None" + ], + "Hash": "EE48C3D0F81474A6548562C928D45A6741F64643360669B034D4730A0E7232E0" + } + }, + { + "Name": "DomainEvents.cs", + "Summary": { + "Summary": "This code defines abstract and concrete classes for repository entity events, enabling the tracking of create, update, and delete operations with associated entities.", + "Exceptions": "None", + "Features": "RepositoryEntityEvent is an abstract class that serves as a base for events related to repository operations. It inherits from EventBase and includes an Entity property to hold the entity involved in the event. The EventType property is abstract, requiring subclasses to implement it with specific event types (Create, Update, Delete). The three concrete classes (RepositoryEntityCreatedEvent, Updated, Deleted) each override EventType to return their respective event types, providing clear event identification for repository operations.", + "Roles": [ + "RepositoryEntityEvent: Abstract base class for repository entity events, containing the entity and requiring EventType implementation.", + "RepositoryEntityCreatedEvent: Implements EventType as \u0027Create\u0027 for entity creation events.", + "RepositoryEntityUpdatedEvent: Implements EventType as \u0027Update\u0027 for entity update events.", + "RepositoryEntityDeletedEvent: Implements EventType as \u0027Delete\u0027 for entity deletion events." + ], + "Hash": "206A61A7A32583F2D6C2D468654FAEA5AD53246513877C81FBDBBA8D7102917A" + } + } + ], + "Directories": [ + { + "Name": "Abstractions", + "Path": "src/Repositories/FluentCMS.Infrastructure.Repositories/Abstractions", + "FolderSummary": "The Abstractions folder houses interfaces and abstractions for database management, data access layers, validation, repository patterns, query specifications, pagination, and initialization conditions in the project\u0027s architecture.", + "Files": [ + { + "Name": "ISchemaValidator.cs", + "Summary": { + "Summary": "Defines a contract for validating and creating database schemas. Schema validators run before data seeders to ensure required database structures exist.", + "Exceptions": "ISchemaValidator.cs", + "Features": "ISchemaValidator.cs", + "Roles": [ + "ISchemaValidator" + ], + "Hash": "F09F757D47224AC2ED78A4AB44403680C6BD9EE7F46DA184675388E6238903A6" + } + }, + { + "Name": "IDbInitializationCondition.cs", + "Summary": { + "Summary": "This interface defines a contract for evaluating whether database seeding or initialization operations should proceed based on runtime conditions, such as environment or configuration.", + "Exceptions": "The file is a standard C# interface definition with no unexpected elements, errors, or unconventional inclusions.", + "Features": "Exports the IDbInitializationCondition interface with a Name property for logging and a ShouldExecute method that asynchronously determines if seeding should execute, supporting cancellation tokens.", + "Roles": [ + "Interface", + "Abstraction" + ], + "Hash": "05F81BF5AD48BA0A1225B5D034E2D834715FC7E7692224B7C38B61D0849B28F1" + } + }, + { + "Name": "IDefaultDatabaseArea.cs", + "Summary": { + "Summary": "The IDefaultDatabaseArea interface is defined in the FluentCMS.Infrastructure.Repositories.Abstractions namespace. It inherits from the IDatabaseArea interface and does not contain any additional members or methods.", + "Exceptions": "", + "Features": "", + "Roles": [ + "interface" + ], + "Hash": "2C6B94EBD7ED4D9F1964FA6863B45BC461BD56A3DC6D91FDA3ACAB02B97B05FF" + } + }, + { + "Name": "IRepository.cs", + "Summary": { + "Summary": "The \u0060IRepository\u003CTEntity\u003E\u0060 interface defines a standard set of asynchronous CRUD operations and a fluent query API for the Repository Pattern. It ensures that any implementing class adheres to a consistent interface for data manipulation and querying, promoting code reusability and maintainability.", + "Exceptions": "The provided code file does not contain any exceptions or error handling mechanisms. The interface defines standard CRUD operations and a query specification method without any explicit error handling.", + "Features": "The interface provides a fluent API for querying through the \u0060Query\u0060 method, which returns an \u0060IQuerySpecification\u003CTEntity\u003E\u0060 object. This allows for building complex queries in a fluent manner. The interface also includes standard CRUD operations (Add, AddRange, Update, Remove, RemoveRange) with support for asynchronous operations via \u0060CancellationToken\u0060.", + "Roles": [ + "Data Access Layer (DAL) Interface", + "Repository Pattern Implementation" + ], + "Hash": "AE6A663FF478CEF5B3A768AC0F6E61558E7E122E2CD2253FA40CF7C2AED9A91B" + } + }, + { + "Name": "IDatabaseArea.cs", + "Summary": { + "Summary": "Marker interface to define database scope/context for repository configuration. Implementations group entities to specific databases.", + "Exceptions": "", + "Features": "This is a marker interface - no methods required. Specific database scopes inherit from this interface to create type-safe database groupings.", + "Roles": [ + "Repository Configuration", + "Database Grouping" + ], + "Hash": "C50817A70BFEEFD1F0A3DA7FECC6F3068C75A0C57448FA30FFCF821675AE2E88" + } + }, + { + "Name": "IDataSeeder.cs", + "Summary": { + "Summary": "Defines a contract for seeding data into a database. Implementations should provide priority-based execution and existence checking.", + "Exceptions": "None", + "Features": "None", + "Roles": [ + "None" + ], + "Hash": "149A85A35853306E1949949E95DD137A4E0DADC5CC3A8FD3A1125D8CC049D8D9" + } + }, + { + "Name": "IPagedResult.cs", + "Summary": { + "Summary": "Pagination result wrapper", + "Exceptions": "", + "Features": "", + "Roles": [ + "Pagination", + "Result Wrapper" + ], + "Hash": "5D6A1CBEA7ADBB8E58B31C94A7A3EA9A9473633B51FDB36AC37A388E3861F59D" + } + }, + { + "Name": "IQuerySpecification.cs", + "Summary": { + "Summary": "The IQuerySpecification interface defines a comprehensive fluent API for building and executing queries on entities in a repository, supporting operations like filtering, projection, ordering, aggregation, and pagination.", + "Exceptions": "The interface returns IQuerySpecification\u003CTEntity\u003E for ordering methods (OrderBy, etc.), but comments indicate it should return IRepositoryOrderedQuery\u003CT\u003E for proper constraints, suggesting a potential refactoring or documentation mismatch.", + "Features": "Features include LINQ-style filtering with Where, projection with Select, Distinct; ordering with OrderBy, OrderByDescending, ThenBy, ThenByDescending; terminal operations such as SingleOrDefault, Single, ToList, ToArray, AsAsyncEnumerable; aggregates like Count and Any; operations requiring ordering like Skip and Take; pagination with ToPagedResult; and First/Last operations.", + "Roles": [ + "Interface", + "Abstraction" + ], + "Hash": "F4D0EE219662F8DCB9B24839FDC480E57AE7ECFF2483FE527622CC48698B21AD" + } + } + ], + "Directories": [] + } + ] + }, + { + "Name": "FluentCMS.Infrastructure.Repositories.EntityFramework.SqlServer", + "Path": "src/Repositories/FluentCMS.Infrastructure.Repositories.EntityFramework.SqlServer", + "FolderSummary": "This folder is responsible for configuring and setting up SQL Server database connections and Entity Framework integration within the FluentCMS project\u0027s infrastructure repositories layer.", + "Files": [ + { + "Name": "SqlServerDatabaseConfiguration.cs", + "Summary": { + "Summary": "Extension methods for configuring SQL Server database provider", + "Exceptions": "Throws ArgumentNullException if builder is null, ArgumentException if connectionString is null or whitespace", + "Features": "Configures SQL Server database provider using a connection string and optional SQL Server-specific options", + "Roles": [ + "Database Configuration", + "Entity Framework" + ], + "Hash": "D79196759ADB3935D795EA3E2705E30DC2BA449A6822938321818A4A54632986" + } + }, + { + "Name": "FluentCMS.Infrastructure.Repositories.EntityFramework.SqlServer.csproj", + "Summary": { + "Summary": "None", + "Exceptions": "None", + "Features": "None", + "Roles": [ + "None" + ], + "Hash": "403B7635A79D518DD098D804097D39E4F62161E3A0FA19E47BB1D19B10BEFCA3" + } + } + ], + "Directories": [] + }, + { + "Name": "FluentCMS.Infrastructure.Repositories.EntityFramework", + "Path": "src/Repositories/FluentCMS.Infrastructure.Repositories.EntityFramework", + "FolderSummary": "This folder implements Entity Framework-based repositories for FluentCMS, handling CRUD operations, query building, entity tracking, data seeding, schema validation, interceptors, configurations, and exception management.", + "Files": [ + { + "Name": "Repository.cs", + "Summary": { + "Summary": "Repository class for Entity Framework operations", + "Exceptions": "ArgumentNullException.ThrowIfNull", + "Features": "CRUD operations, async methods, cancellation tokens, query specification", + "Roles": [ + "CRUD operations", + "Entity tracking management", + "Query building" + ], + "Hash": "3EBE19F03E873A84F90E316059D0BF33D9BA521A03543679D2EFE6BC86B7B3EA" + } + }, + { + "Name": "BaseSchemaValidator.cs", + "Summary": { + "Summary": "BaseSchemaValidator.cs is an abstract class that implements ISchemaValidator. It provides a base implementation for creating and validating database schemas using Entity Framework. The class is generic, taking a TDbContext type constrained to DbContext. It includes methods for creating the schema via a generated SQL script and validating the existence of tables. Logging is handled via an injected ILogger instance. The class is abstract and requires derived classes to implement the Priority property and can override the CreateSchema and ValidateSchema methods if needed. The methods are asynchronous and use CancellationToken for cancellation support.", + "Exceptions": "BaseSchemaValidator.cs", + "Features": "BaseSchemaValidator.cs", + "Roles": [ + "BaseSchemaValidator.cs", + "BaseSchemaValidator.cs" + ], + "Hash": "9830489469C692B8162CEA4089C882CA488EFA1E82A425E9C32043A8132D3E46" + } + }, + { + "Name": "BaseDataSeeder.cs", + "Summary": { + "Summary": "BaseDataSeeder.cs is an abstract class that serves as a base for seeding data in a database context. It is generic with a type parameter TDbContext which must be a DbContext. The class implements the IDataSeeder interface and provides a logger for logging operations. The class includes abstract and virtual methods for checking if seeding is needed and for performing the actual seeding. The Priority property is abstract, requiring derived classes to implement it. The ShouldSeed method checks for existing data and returns whether seeding is necessary. The SeedData method is abstract and must be implemented by derived classes to seed data.", + "Exceptions": "None", + "Features": "The class includes logging via ILogger, abstract and virtual methods, generic type constraints, and a base class for data seeding operations.", + "Roles": [ + "Base class for data seeding", + "Abstract class with generic type parameter", + "Implements IDataSeeder interface", + "Includes logging functionality", + "Provides methods for checking data existence and seeding" + ], + "Hash": "0860222318AFC7102F0F27EB992586D0C31D963FD5BB82CC8EFD39C5D4C8A0F8" + } + }, + { + "Name": "_GlobalUsings.cs", + "Summary": { + "Summary": "This file defines global using statements for various namespaces from FluentCMS and Microsoft libraries, allowing them to be used globally in the project\u0027s C# code without explicit using directives in each file.", + "Exceptions": "This file appears standard for a C# project with global usings; no unexpected elements are present.", + "Features": "Exports global access to namespaces for event bus abstractions, repository abstractions, Entity Framework interceptors, Entity Framework core, diagnostics, dependency injection, hosting, logging, LINQ expressions, diagnostics, and text encoding.", + "Roles": [ + "Configuration" + ], + "Hash": "88E576359AAB227AF1D962E86E2FF4F9643D4CF637C072BEEF753C298D7DDAE0" + } + }, + { + "Name": "DbContextExtensions.cs", + "Summary": { + "Summary": "This code provides methods to check if any tables in the database have data or exist, using reflection to interact with Entity Framework\u0027s DbContext. It\u0027s part of a FluentCMS infrastructure repository.", + "Exceptions": "The code contains a method that catches exceptions and ignores them, which might mask errors. However, the user requested analysis of the code file and output valid JSON, so this is not included in the JSON output.", + "Features": "The code includes reflection usage to dynamically call DbSet.AnyAsync, which is a common pattern in Entity Framework Core for dynamic queries. However, this approach can be error-prone and less efficient than using LINQ queries directly.", + "Roles": [ + "Database administrator", + "Developer", + "Database analyst" + ], + "Hash": "5452E4DD24EA28217361B5AB183A0FD1E451EB501B84AF0DD2D47CFD96DAEBF1" + } + }, + { + "Name": "FluentCMS.Infrastructure.Repositories.EntityFramework.csproj", + "Summary": { + "Summary": "none", + "Exceptions": "none", + "Features": "none", + "Roles": [ + "none" + ], + "Hash": "19F0F7EA30A13902691275E1752ADA75DDC5F48D3FA40CF2F13788BF8381BB98" + } + }, + { + "Name": "QuerySpecification.cs", + "Summary": { + "Summary": "QuerySpecification class for building and executing entity queries using Entity Framework. Implements IQuerySpecification\u003CTEntity\u003E with LINQ-style operations, ordering, pagination, and terminal methods.", + "Exceptions": "Throws InvalidOperationException for Skip, Take, and First/Last operations without prior ordering.", + "Features": "Supports filtering, ordering, pagination, and asynchronous execution with cancellation tokens.", + "Roles": [ + "Repository Pattern", + "Specification Pattern", + "Entity Framework Query Builder" + ], + "Hash": "E32AEEF55AA4CE48A85BFE4BBFD9D231B8CAD60C0FF51909DD06D38EC53173B1" + } + } + ], + "Directories": [ + { + "Name": "Interceptors", + "Path": "src/Repositories/FluentCMS.Infrastructure.Repositories.EntityFramework/Interceptors", + "FolderSummary": "The \u0022Interceptors\u0022 folder contains Entity Framework Core save changes interceptors that handle domain events and auditable entity updates during database operations.", + "Files": [ + { + "Name": "DomainEventSaveChangesInterceptor.cs", + "Summary": { + "Summary": "This file defines an Entity Framework save changes interceptor that publishes repository-level events (created, updated, deleted) based on entity state changes during save operations.", + "Exceptions": "The interceptor publishes infrastructure events rather than actual domain events from the entities themselves, despite the class comment referring to \u0027domain events\u0027; it also synchronously waits on async event publishing in the sync version.", + "Features": "Intercepting EF save changes synchronously and asynchronously; publishing events for added, modified, or deleted entities using an IEventPublisher.", + "Roles": [ + "Interceptor" + ], + "Hash": "C51285B435D8BF9E4ED3E34496DECA0F3422955DD8EE38C588EC080F4EFDA5F2" + } + }, + { + "Name": "AuditableEntitySaveChangesInterceptor.cs", + "Summary": { + "Summary": "This file implements an Entity Framework save changes interceptor that automatically populates audit fields (CreatedAt, CreatedBy, UpdatedAt, UpdatedBy, Version) for entities implementing IAuditableEntity during save operations.", + "Exceptions": "None; the code behaves as expected for an audit interceptor.", + "Features": "Implements ISaveChangesInterceptor interface with synchronous and asynchronous SavingChanges methods; updates audit fields based on entity state (Added or Modified); retrieves current user from IUserContext service if available.", + "Roles": [ + "Interceptor" + ], + "Hash": "5C260AEC63D5FA29350926E417165F0FD57158E9B0FA9F622218DD87884E0F8F" + } + } + ], + "Directories": [] + }, + { + "Name": "Configuration", + "Path": "src/Repositories/FluentCMS.Infrastructure.Repositories.EntityFramework/Configuration", + "FolderSummary": "The Configuration folder is responsible for encapsulating classes and extensions that configure database connections, Entity Framework DbContext options, data seeding, schema validation, service registrations, and related hosted services to set up and manage the application\u0027s database infrastructure.", + "Files": [ + { + "Name": "ServiceCollectionExtensions.cs", + "Summary": { + "Summary": "Extension methods for IServiceCollection to configure the DatabaseManager in FluentCMS Infrastructure Repositories Entity Framework.", + "Exceptions": "Throws InvalidOperationException when DatabaseManager hasn\u0027t been configured.", + "Features": "Includes methods for configuring database providers, connection strings, data seeding, schema validation, and registering DbContexts with interceptors.", + "Roles": [ + "DatabaseManagerConfiguration", + "DbContextRegistration", + "DataSeeding", + "SchemaValidation", + "ServiceRegistration" + ], + "Hash": "CE2F9044040A7730E058608F6F2942FB9CB41537531532F5E845E17A9C2F9834" + } + }, + { + "Name": "DatabaseConfiguration.cs", + "Summary": { + "Summary": "Represents the configuration for a database connection including provider and connection settings", + "Exceptions": "ArgumentNullException.ThrowIfNull(builder) in Apply method", + "Features": "Configuration of DbContextOptions, Data seeding, Schema validation, Connection string, Marker type, Service descriptors", + "Roles": [ + "Database connection configuration", + "Entity Framework DbContext options configuration", + "Data seeding setup", + "Schema validation setup" + ], + "Hash": "17EF37C19ACA43FC0677814D33DEF014BC84DBB458B9F0436BED4DC6FA081717" + } + }, + { + "Name": "SchemaValidatorService.cs", + "Summary": { + "Summary": "This file defines and implements a service for validating and initializing database schemas across multiple configured databases in the FluentCMS infrastructure, executing schema validators in global priority order while respecting conditional checks and exception handling options.", + "Exceptions": "The service includes a catch block that allows ignoring exceptions based on configuration options, which might be unexpected as it could silently fail validation in some cases.", + "Features": "Implements ISchemaValidatorService interface; supports running multiple schema validators across databases; orders validators by priority; conditions validation on custom conditions; handles exceptions with configurable ignore settings; provides detailed logging; uses dependency injection for validators;", + "Roles": [ + "Service", + "Validator" + ], + "Hash": "C7C5AD1B3D86FFF8B0EF3E6B9850F8234BEF30439562D9B31498F6FF847736B3" + } + }, + { + "Name": "DatabaseManagerOptions.cs", + "Summary": { + "Summary": "Options class for configuring database connections for multiple DbContexts. Supports both default configuration and marker-based specific configurations.", + "Exceptions": "InvalidOperationException: Thrown when GetDefaultConfiguration() is called without a default configuration being set.", + "Features": "The class supports configuring a default database and specific databases for DbContexts marked with a marker interface. It uses a dictionary to store configurations keyed by marker type.", + "Roles": [ + "DatabaseManagerOptions", + "IServiceCollection" + ], + "Hash": "AC29D7A533660062D5B30F769B00FD63F76B3314FAD8F560E8E53F9BDF379B99" + } + }, + { + "Name": "DataSeederService.cs", + "Summary": { + "Summary": "The DataSeederService class implements the IDataSeederService interface to seed the database with initial data. It uses dependency injection to access the service provider, database manager options, and logger. The service checks conditions for seeding, collects all registered seeders, sorts them by priority, and executes them in order. It handles exceptions and logs progress and errors appropriately.", + "Exceptions": "The service catches exceptions during seeding. If the configuration\u0027s IgnoreExceptions flag is set, it logs the error but continues. Otherwise, it rethrows the exception.", + "Features": "Key features include: global priority-based execution of seeders, condition-based skipping of seeders, handling of default configurations, and detailed logging of seeding activities.", + "Roles": [ + "Database Initializer", + "Data Seeder", + "Dependency Injection Consumer" + ], + "Hash": "EB7057A3F37B2C1DC36693660150DFDD7FA8264ED2E0E2228A6B5465858693E4" + } + }, + { + "Name": "DataInitializerHostedService.cs", + "Summary": { + "Summary": "Hosted service responsible for performing database schema validation and data seeding operations during application startup.", + "Exceptions": "Throws an exception if any error occurs during initialization, preventing application startup.", + "Features": "Includes schema validation and data seeding, with detailed logging for each step.", + "Roles": [ + "IHostedService", + "IServiceProvider", + "ILogger" + ], + "Hash": "181D1538C1B2F754B30BAC4E23BA79DDF31E2F0837188BCC1F663E7CC872392E" + } + }, + { + "Name": "DatabaseConfigurationBuilder.cs", + "Summary": { + "Summary": "Default implementation of IDatabaseConfigurationBuilder", + "Exceptions": "", + "Features": "This class is used to build the DatabaseConfiguration object and manage service descriptors for Entity Framework configuration in the FluentCMS project.", + "Roles": [ + "Infrastructure.Repositories.EntityFramework.Configuration" + ], + "Hash": "996BD9BD3B40BDC6C257F1E95E368BA240C58D4781B1A6B50F162C8D05513967" + } + } + ], + "Directories": [] + }, + { + "Name": "Exceptions", + "Path": "src/Repositories/FluentCMS.Infrastructure.Repositories.EntityFramework/Exceptions", + "FolderSummary": "This folder houses custom exception classes and codes, including specialized types for entity not found errors and enhanced exception handling with validation and source capture capabilities, to standardize error management across the project\u0027s infrastructure and repositories.", + "Files": [ + { + "Name": "ExceptionCodes.cs", + "Summary": { + "Summary": "ExceptionCodes.cs contains a class with a constant string for entity not found error.", + "Exceptions": "EntityNotFound", + "Features": "Single constant string defined in the ExceptionCodes class within the FluentCMS.Infrastructure.Repositories.EntityFramework.Exceptions namespace.", + "Roles": [ + "Developer", + "Maintainer" + ], + "Hash": "8CE3972E61173B926B9F9CED7E0EC1CBFC0A8A9905914570A8DCBDC5FDC8FE1E" + } + }, + { + "Name": "EntityNotFoundException.cs", + "Summary": { + "Summary": "The EntityNotFoundException class is used to indicate that an entity was not found in the system. It inherits from EnhancedException and provides two constructors for different scenarios: one specifying the entity name and ID, and another specifying only the entity name. A generic version of the exception, EntityNotFoundException\u003CT\u003E, is also provided, which uses the type name of T as the entity name in the message.", + "Exceptions": "EntityNotFoundException is thrown when an entity is not found in the system. The generic version EntityNotFoundException\u003CT\u003E is used when the entity type is known at compile time.", + "Features": "The class includes two constructors: one that takes an entity name and ID, and another that takes only the entity name. The generic version simplifies usage by automatically using the type name of T as the entity name.", + "Roles": [ + "Infrastructure", + "Repositories", + "Exceptions" + ], + "Hash": "5E30413E89AFAFFE8369E5F465E17125B338CDC73A51F91B8A4CD8D09225EC10" + } + }, + { + "Name": "EnhancedException.cs", + "Summary": { + "Summary": "EnhancedException class for handling exceptions with enhanced information, including error codes, method context, and validation errors.", + "Exceptions": "Exception", + "Features": "EnhancedException provides detailed exception information including the type and method where the exception occurred, a list of error codes with descriptions, and a comprehensive string representation. It supports adding single or multiple errors and includes constructors for different scenarios.", + "Roles": [ + "Exception Handling", + "Validation Error Reporting", + "Exception Source Capture" + ], + "Hash": "C4E933745E1E092A63A7169A3D84DBC170D925E9FB67AF847A7C97972ECD6344" + } + } + ], + "Directories": [] + } + ] + } + ] + }, + { + "Name": "Logging", + "Path": "src/Logging", + "FolderSummary": "Assistant: The user is asking for a concise 1-sentence summary of the folder\u0027s responsibility in the project. The folder is named \u0022Logging\u0022 and contains files and a subfolder \u0022FluentCMS.Infrastructure.Logging\u0022.\n\nI need to reason step by step. This seems like a project structure, possibly in a software project, maybe a CMS (Content Management System).\n\nThe name \u0022FluentCMS\u0022 suggests it\u0027s related to FluentCMS, an open-source CMS built with .NET.\n\nThe folder \u0022Logging\u0022 in \u0022FluentCMS.Infrastructure.Logging\u0022 is part of the infrastructure layer, handling logging.\n\nWhat does logging entail? Logging is the process of recording messages, events, or data during the execution of a program, often for debugging, monitoring, or auditing purposes.\n\nSo, the folder\u0027s responsibility is likely to provide logging infrastructure for the CMS.\n\nThe user specifies: \u0022Provide a concise 1-sentence summary of this folder\u0027s responsibility in the project.\u0022\n\nI need to make it concise and one sentence.\n\nKeep it economical, no yapping.\n\nResponse should be direct.This folder is responsible for providing the logging infrastructure and utilities within the FluentCMS project, enabling the recording and management of application events, errors, and operational insights for debugging and monitoring.", + "Files": [], + "Directories": [ + { + "Name": "FluentCMS.Infrastructure.Logging", + "Path": "src/Logging/FluentCMS.Infrastructure.Logging", + "FolderSummary": "The FluentCMS.Infrastructure.Logging folder is responsible for providing infrastructure components and configurations for logging, including extensions for SQLite-based logger setup and factory initialization.", + "Files": [ + { + "Name": "FluentCMS.Infrastructure.Logging.csproj", + "Summary": { + "Summary": "This .csproj file defines the FluentCMS.Infrastructure.Logging project as a .NET library targeting net10.0, with ImplicitUsings and Nullable enabled, and includes a reference to Serilog.AspNetCore for ASP.NET Core logging.", + "Exceptions": "The .NET target framework net10.0 is not yet publicly released; the Serilog.AspNetCore version 10.0.0 may not correspond to real releases.", + "Features": "Enables Serilog.AspNetCore for structured logging in ASP.NET Core applications.", + "Roles": [ + "Library", + "Infrastructure" + ], + "Hash": "916CE8C044FC699CBBF2437D5EFAEDA9CDEE05488268F55876D9BBF96E5C7968" + } + }, + { + "Name": "SqliteConfigurationExtensions.cs", + "Summary": { + "Summary": "This code configures Serilog logging for a .NET application, setting minimum levels, overrides, and output sinks (console and file). It integrates with the host builder and returns an ILoggerFactory for dependency injection.", + "Exceptions": "None", + "Features": "The code defines a static class \u0060SqliteConfigurationExtensions\u0060 with a method \u0060InitLogFactory\u0060 that configures Serilog logging. It sets up a logger with minimum debug level, overrides Microsoft to warning, enriches from log context, and writes to console and a file with daily rolling. The method uses \u0060IHostBuilder\u0060 to integrate Serilog and returns an \u0060ILoggerFactory\u0060.", + "Roles": [ + "LoggerConfiguration", + "ILoggerFactorySetup" + ], + "Hash": "01A8319EE89E9E6F1C23D6B69B4F195D96926EB5F2A00789BBEBE0733C0BF7A5" + } + } + ], + "Directories": [] + } + ] + }, + { + "Name": "Plugins", + "Path": "src/Plugins", + "FolderSummary": "The Plugins folder in FluentCMS handles the infrastructure for implementing and managing extensible plugins, including abstractions and concrete components to support modular functionality within the content management system.", + "Files": [], + "Directories": [ + { + "Name": "FluentCMS.Infrastructure.Plugins.Abstractions", + "Path": "src/Plugins/FluentCMS.Infrastructure.Plugins.Abstractions", + "FolderSummary": "This folder defines the abstract contracts, attributes, and interfaces (such as the IPluginStartup interface and PluginAttribute) that establish the foundational structure for plugins within the FluentCMS system.", + "Files": [ + { + "Name": "PluginAttribute.cs", + "Summary": { + "Summary": "This file defines a custom attribute, PluginAttribute, which marks a class as a plugin startup class for automatic discovery and loading by the plugin system in FluentCMS.", + "Exceptions": "The attribute is currently empty but includes comments about potential future extensions for metadata.", + "Features": "Implements a sealed attribute class that inherits from System.Attribute, with AttributeUsage specifying it applies only to classes and not inherited.", + "Roles": [ + "Attribute" + ], + "Hash": "1FD1AEA4334D5D218DC5ECFD4A626E6D5443CCABD4A32CC9C66EB0307418B1AF" + } + }, + { + "Name": "FluentCMS.Infrastructure.Plugins.Abstractions.csproj", + "Summary": { + "Summary": "Project file for FluentCMS.Infrastructure.Plugins.Abstractions, targeting .NET 10.0 with implicit usings enabled and nullable reference types enabled.", + "Exceptions": "None", + "Features": "None", + "Roles": [ + "Project File" + ], + "Hash": "8AC29D0288D2A0B3396437FFB0AE7150C18BE112EA1899D3C12C15A86B78D25E" + } + }, + { + "Name": "IPluginStartup.cs", + "Summary": { + "Summary": "This C# file defines the IPluginStartup interface, which serves as the central abstraction for all plugins in the FluentCMS plugin system, requiring implementations to handle service configuration and application pipeline setup in an ASP.NET Core environment.", + "Exceptions": "", + "Features": "Provides virtual default implementations for properties like Name, Version, ConfigureServicesPriority, and ConfigurePriority; requires implementations of ConfigureServices and Configure methods to integrate plugin-specific services and middleware.", + "Roles": [ + "Interface", + "Plugin Contract" + ], + "Hash": "381EFE1A1F5C881E65CB8A27024C4E1FAC8A5A344B5C18F292A41A4B4C956A87" + } + } + ], + "Directories": [] + }, + { + "Name": "FluentCMS.Infrastructure.Plugins", + "Path": "src/Plugins/FluentCMS.Infrastructure.Plugins", + "FolderSummary": "The FluentCMS.Infrastructure.Plugins folder handles the core infrastructure for the plugin system in FluentCMS, encompassing discovery, loading, initialization, metadata management, and configuration options.", + "Files": [ + { + "Name": "PluginMetadata.cs", + "Summary": { + "Summary": "PluginMetadata class and PluginStatus enum from FluentCMS.Infrastructure.Plugins namespace", + "Exceptions": "None", + "Features": "Class with properties and enum with status values", + "Roles": [ + "PluginMetadata: Represents plugin metadata with properties like name, version, type, instance, status, and error message.", + "PluginStatus: Enum defining possible plugin status states." + ], + "Hash": "64FA488AE2DA55498FB6D8459E4B52F96A46D6BD2B41119B0DE0384F0C62CC5B" + } + }, + { + "Name": "PluginSystemExtensions.cs", + "Summary": { + "Summary": "The PluginSystemExtensions class provides methods to add and use the plugin system in a .NET application, configuring it via options and starting it during application startup.", + "Exceptions": "ArgumentNullException.ThrowIfNull(services) and ArgumentNullException.ThrowIfNull(app) are used to validate parameters.", + "Features": "Extension methods for IServiceCollection and IApplicationBuilder to integrate the plugin system.", + "Roles": [ + "PluginDiscovery", + "PluginInitializer", + "PluginLoader" + ], + "Hash": "C95980A85CEF9DB035712CD44781EC2A5952C51CAC15CFD4C686C190FB83B095" + } + }, + { + "Name": "NullArgumentException.cs", + "Summary": { + "Summary": "NullArgumentException class for handling null or empty argument exceptions in FluentCMS infrastructure plugins.", + "Exceptions": "ArgumentException", + "Features": "Static methods for null and empty argument checks with automatic parameter name capture via [CallerArgumentExpression].", + "Roles": [ + "Infrastructure", + "Plugins" + ], + "Hash": "33440C2E894A28C734B5CA94E98F87C47238E6A11E26D81431D0B17B31469288" + } + }, + { + "Name": "PluginManager.cs", + "Summary": { + "Summary": "The PluginManager class implements the IPluginManager interface, managing the lifecycle of plugins in a .NET application. It handles plugin discovery, initialization, configuration, startup, and cleanup.", + "Exceptions": "The class handles exceptions during plugin configuration and startup, with options to ignore errors or throw exceptions based on PluginSystemOptions.IgnoreErrors. It also manages cancellation tokens for timeout and cancellation scenarios.", + "Features": "Key features include plugin discovery via IPluginDiscovery, initialization via IPluginInitializer, loading of plugin types, service configuration, application startup, and unloading of Application Library Components (ALCs) after startup.", + "Roles": [ + "PluginDiscovery", + "PluginInitializer", + "PluginLoader", + "Logger", + "PluginSystemOptions" + ], + "Hash": "207A14CDBDC669A71C955BD0A6E010E1BA37B35A0FEA69A7059D837EF14E57A8" + } + }, + { + "Name": "_GlobalUsings.cs", + "Summary": { + "Summary": "The _GlobalUsings.cs file contains a list of global using directives for the FluentCMS infrastructure plugins and Microsoft.AspNetCore and Microsoft.Extensions namespaces. The file includes global usings for FluentCMS.Infrastructure.Plugins.Abstractions, FluentCMS.Infrastructure.Plugins.Discovery, FluentCMS.Infrastructure.Plugins.Initializer, FluentCMS.Infrastructure.Plugins.Loader, Microsoft.AspNetCore.Builder, Microsoft.Extensions.Configuration, Microsoft.Extensions.DependencyInjection, Microsoft.Extensions.Logging, System.Diagnostics.CodeAnalysis, System.Reflection, System.Runtime.CompilerServices, and System.Runtime.Loader. The file does not contain any exceptions, features, hash, or roles as per the provided code snippet.", + "Exceptions": "None", + "Features": "None", + "Roles": [ + "None" + ], + "Hash": "2FC962CECD10747779181A92DEBF51F884E64F416D228F6DEB8A54354D295236" + } + }, + { + "Name": "FluentCMS.Infrastructure.Plugins.csproj", + "Summary": { + "Summary": "None", + "Exceptions": "None", + "Features": "None", + "Roles": [ + "None" + ], + "Hash": "372BF434F8B0F36F2160A6B451180FCF56D0E359B223BC4EE66E04E5801ADDCD" + } + }, + { + "Name": "PluginSystemOptions.cs", + "Summary": { + "Summary": "This file defines the PluginSystemOptions class, which provides configuration options for the FluentCMS plugin system to control plugin discovery, loading, and management.", + "Exceptions": "The class includes an internal property for tracking registered AssemblyLoadContexts and requires an ILoggerFactory instance set to default!.", + "Features": "Configurable assembly scan patterns, options to ignore loading errors, plugin load timeout, ALC unloading after startup, strict timeout handling, and an external logger factory.", + "Roles": [ + "Configuration", + "Options" + ], + "Hash": "9144C296577227E767F08B2ED86CB5083E554A755E366FEBA66B39654D575DA5" + } + } + ], + "Directories": [ + { + "Name": "Loader", + "Path": "src/Plugins/FluentCMS.Infrastructure.Plugins/Loader", + "FolderSummary": "The Loader folder is responsible for managing plugin loading, discovery, and assembly management in the project\u0027s plugin system, utilizing classes like PluginLoader to scan for types marked with PluginAttribute and implement interfaces such as IPluginStartup, while handling exceptions and logging via a dedicated PluginLoadContext for collectible assemblies.", + "Files": [ + { + "Name": "PluginLoaderException.cs", + "Summary": { + "Summary": "Exception thrown when plugin loading fails.", + "Exceptions": "PluginLoaderException", + "Features": "This class inherits from the base Exception class and provides two constructors: one that takes a message string and another that takes a message and an inner exception. It is used to handle errors during plugin loading in the FluentCMS infrastructure.", + "Roles": [ + "Exception", + "PluginLoaderException" + ], + "Hash": "367771CDFCB6AF564504D729A6C6F385CAAA69198E900441C74EED0013B1CE67" + } + }, + { + "Name": "PluginLoader.cs", + "Summary": { + "Summary": "PluginLoader.cs implements a plugin loading mechanism for FluentCMS. It defines an interface IPluginLoader and a class PluginLoader that loads plugin types from assembly files, using a PluginLoadContext to handle collectible assemblies and prevent memory leaks.", + "Exceptions": "Handles OperationCanceledException and other exceptions, with logging and optional error ignoring via PluginSystemOptions.IgnoreErrors.", + "Features": "Supports preloaded assemblies, collectible assembly loading, plugin type discovery via PluginAttribute and IPluginStartup interface, and error handling.", + "Roles": [ + "Interface: IPluginLoader defines a method to load plugin types.", + "Class: PluginLoader implements IPluginLoader, managing assembly loading and plugin discovery.", + "Logger: Uses ILogger for debugging and error logging.", + "Options: PluginSystemOptions provides configuration settings.", + "Assembly Loading: Uses PluginLoadContext for collectible assemblies.", + "Type Discovery: Scans assemblies for types marked with PluginAttribute and implementing IPluginStartup." + ], + "Hash": "55FC77E3D8FAD145AB526918140B4194C3DC17A67B430958D2D17C78C0F43A5F" + } + }, + { + "Name": "PluginLoadContext.cs", + "Summary": { + "Summary": "Collectible ALC that resolves dependencies relative to the plugin\u2019s main assembly. Uses AssemblyDependencyResolver to locate dependencies and unmanaged DLLs. Overrides Load and LoadUnmanagedDll methods to load assemblies and unmanaged DLLs from resolved paths. Returns null or nint.Zero if resolution fails. Internal class within FluentCMS infrastructure.", + "Exceptions": "None", + "Features": "Collectible AssemblyLoadContext", + "Roles": [ + "PluginLoader", + "DependencyResolver" + ], + "Hash": "B9163F4BB25A08794474D631F365BF0F87295FD4C33B6AABAFDB6151BFB6C4BB" + } + } + ], + "Directories": [] + }, + { + "Name": "Initializer", + "Path": "src/Plugins/FluentCMS.Infrastructure.Plugins/Initializer", + "FolderSummary": "The Initializer folder is responsible for managing the initialization of plugins in the system, including error handling, logging, configuration-based behavior, exception management, and providing plugin metadata.", + "Files": [ + { + "Name": "PluginInitializerException.cs", + "Summary": { + "Summary": "PluginInitializerException is a custom exception class in the FluentCMS.Infrastructure.Plugins.Initializer namespace. It inherits from the base Exception class and provides two constructors: one that takes a message string and another that takes both a message and an inner exception. This allows for both simple exception creation and chaining of exceptions with additional context.", + "Exceptions": "This class is designed to handle exceptions during the initialization of plugins in the FluentCMS system. It provides a way to capture and propagate error information when plugin initialization fails.", + "Features": "The class includes two constructors that mirror the base Exception constructors, enabling both basic exception handling and more complex scenarios where an inner exception is provided.", + "Roles": [ + "Exception Handling", + "Error Propagation", + "Plugin Initialization Error" + ], + "Hash": "B4A9169558A2F2092ED391DF449575AFE97F7881FC609C3381769AC299C635BF" + } + }, + { + "Name": "PluginInitializer.cs", + "Summary": { + "Summary": "The PluginInitializer class implements the IPluginInitializer interface to initialize plugin types. It checks if the plugin type implements IPluginStartup, creates an instance, and handles initialization errors. The class uses logging to record initialization events and errors, and respects the IgnoreErrors setting from PluginSystemOptions to determine whether to ignore errors or throw exceptions.", + "Exceptions": "The Initialize method handles several exceptions: OperationCanceledException (when cancellation is requested), general exceptions (logged and either ignored or thrown as PluginInitializerException based on IgnoreErrors setting), and ArgumentNullException (for null pluginType).", + "Features": "Key features include: validation of plugin type implementation, cancellation handling, instance creation, logging of initialization status, error handling with IgnoreErrors configuration, and returning PluginMetadata with status and error details.", + "Roles": [ + "PluginInitializer: Implements IPluginInitializer to initialize plugins.", + "Logger: Uses ILogger to log initialization and error events.", + "Configuration: Uses PluginSystemOptions to determine error handling behavior.", + "ExceptionHandler: Manages exceptions during plugin initialization.", + "MetadataProvider: Returns PluginMetadata with plugin details and status." + ], + "Hash": "7BCFA6AB0EEDCD6606159F274DC1B1BF575D0FB81E65F7F04CF0F69DCA8C8B46" + } + } + ], + "Directories": [] + }, + { + "Name": "Discovery", + "Path": "src/Plugins/FluentCMS.Infrastructure.Plugins/Discovery", + "FolderSummary": "The Discovery folder implements the plugin discovery mechanism, providing classes, interfaces, and utilities for scanning, loading, and resolving plugin assemblies dynamically within the application\u0027s plugin system.", + "Files": [ + { + "Name": "PluginDiscovery.cs", + "Summary": { + "Summary": "The PluginDiscovery.cs file implements the IPluginDiscovery interface for discovering plugin assemblies in a .NET application. It scans directories for assemblies matching specific patterns, loads them using a MetadataLoadContext, and checks for plugins by verifying the presence of a PluginAttribute and implementation of the IPluginStartup interface.", + "Exceptions": "The class handles exceptions through a try-catch block, logging errors and optionally ignoring them based on the pluginSystemOptions.IgnoreErrors flag. Specific exceptions include PluginDiscoveryException for initialization failures and PluginDiscoveryException for scanning errors.", + "Features": "Key features include scanning for assemblies in specified directories, filtering by scan patterns, loading assemblies dynamically, and checking for plugin attributes and startup interfaces.", + "Roles": [ + "PluginDiscovery: The main class that implements the IPluginDiscovery interface.", + "IPluginDiscovery: The interface defining the Scan method.", + "PluginSystemOptions: A class containing configuration options for plugin discovery.", + "PathAssemblyResolver: A resolver used to load assemblies from probe paths.", + "MetadataLoadContext: Used to load assemblies dynamically.", + "PluginAttribute: An attribute marking classes as plugins.", + "IPluginStartup: An interface that plugin classes must implement." + ], + "Hash": "56DC8FD9B3025AEE188E23A310757B015C0EACBDCE606BA8B191D18294850C47" + } + }, + { + "Name": "PluginDiscoveryException.cs", + "Summary": { + "Summary": "Exception thrown when plugin discovery fails.", + "Exceptions": "PluginDiscoveryException", + "Features": "public class", + "Roles": [ + "Exception" + ], + "Hash": "B3F3AF8DA6A86C68F967F552452643D537C8E225EC17D637C0D8C8DCEE91118B" + } + } + ], + "Directories": [] + } + ] + } + ] + } + ] + } + ] + }, + "IndexedAt": "2026-02-09T08:43:46.7682746Z" +} \ No newline at end of file diff --git a/src/Common/FluentCMS.Infrastructure.Common/README.md b/src/Common/FluentCMS.Infrastructure.Common/README.md new file mode 100644 index 0000000..a42ed79 --- /dev/null +++ b/src/Common/FluentCMS.Infrastructure.Common/README.md @@ -0,0 +1,73 @@ +# FluentCMS.Infrastructure.Common + +This project provides common utilities and base classes for FluentCMS infrastructure components, enabling consistent entity management, auditing, and user context handling across the FluentCMS ecosystem. + +## Key Features + +- **Base Entity Classes**: + - `Entity`: A simple base entity with a unique `Id` property. + - `AuditableEntity`: Extends `Entity` with auditing fields like `CreatedAt`, `UpdatedAt`, `CreatedBy`, `UpdatedBy`, and `Version` for concurrency control. +- **User Context Interface**: `IUserContext` for managing user-related information. +- **Global Usings**: Automatically includes common namespaces like `System.ComponentModel.DataAnnotations` globally to reduce boilerplate code. + +## Installation + +Install the package via NuGet: + +```bash +dotnet add package FluentCMS.Infrastructure.Common +``` + +## Usage + +### Basic Entity + +To create a simple entity, inherit from the `Entity` class: + +```csharp +using FluentCMS.Infrastructure; + +public class MyEntity : Entity +{ + public string Name { get; set; } + // Add more properties as needed +} +``` + +### Auditable Entity + +For entities that require auditing and versioning, inherit from `AuditableEntity`: + +```csharp +using FluentCMS.Infrastructure; + +public class MyAuditableEntity : AuditableEntity +{ + public string Title { get; set; } + public string Content { get; set; } + // Add more properties as needed +} +``` + +### User Context + +To use the user context, you can implement or inject the `IUserContext` interface to access user information: + +```csharp +using FluentCMS.Infrastructure; + +public interface IUserContext +{ + // Define properties like UserId, Username, etc. +} + +// Implement or inject IUserContext in your services. +``` + +## Dependencies + +This library has no external dependencies. It targets .NET 10.0 and uses standard .NET frameworks. + +## License + +This project is licensed under the MIT License. \ No newline at end of file diff --git a/src/Common/README.md b/src/Common/README.md new file mode 100644 index 0000000..da73359 --- /dev/null +++ b/src/Common/README.md @@ -0,0 +1,17 @@ +# Common + +> Shared infrastructure library for FluentCMS containing reusable components and utilities. + +## 📖 About +The Common project is a .NET class library that provides essential, reusable infrastructure components such as base entity classes, auditable entities with versioning, and user context interfaces. It forms the foundation for consistent data handling, auditing, and user management across the entire FluentCMS system, ensuring modularity and maintainability in the broader application architecture. + +## 🚀 Getting Started + +### Prerequisites +* .NET 10.0 (or compatible runtime/SDK for the target framework) + +### Installation +```bash +# Add as a project reference in your solution +dotnet add reference src/Common/FluentCMS.Infrastructure.Common/FluentCMS.Infrastructure.Common.csproj +``` \ No newline at end of file diff --git a/src/Configuration/FluentCMS.Infrastructure.Configuration.EntityFramework.SqlServer/README.md b/src/Configuration/FluentCMS.Infrastructure.Configuration.EntityFramework.SqlServer/README.md new file mode 100644 index 0000000..4615bd0 --- /dev/null +++ b/src/Configuration/FluentCMS.Infrastructure.Configuration.EntityFramework.SqlServer/README.md @@ -0,0 +1,54 @@ +# FluentCMS.Infrastructure.Configuration.EntityFramework.SqlServer + +A SQL Server-specific Entity Framework configuration provider for the FluentCMS Infrastructure. This package enables using SQL Server as the backend for storing and retrieving application configuration data via Entity Framework. + +## Key Features + +- SQL Server database provider integration for FluentCMS configuration. +- Extension methods to easily set up SQL Server-backed configuration in .NET applications. +- Leverages Entity Framework Core for ORM-based configuration storage and retrieval. +- Supports automatic configuration reloading with optional intervals. + +## Installation + +Install the package via NuGet Package Manager: + +``` +dotnet add package FluentCMS.Infrastructure.Configuration.EntityFramework.SqlServer --version 1.0.0 +``` + +## Usage + +To use SQL Server for configuration, add the SQL Server configuration extension to your `IConfigurationBuilder`: + +```csharp +using FluentCMS.Configuration.EntityFramework.SqlServer; +using Microsoft.Extensions.Configuration; + +var builder = new ConfigurationBuilder() + .AddSqlServerConfiguration("Server=your-server;Database=your-db;Trusted_Connection=True;"); + +// Build the configuration +var configuration = builder.Build(); +``` + +Replace `"Server=your-server;Database=your-db;Trusted_Connection=True;"` with your actual SQL Server connection string. + +For configuration with automatic reloading, specify a reload interval: + +```csharp +builder.AddSqlServerConfiguration(connectionString, TimeSpan.FromSeconds(30)); +``` + +## Dependencies + +This package depends on: + +- `Microsoft.EntityFrameworkCore.SqlServer` (version 10.0.2) +- `FluentCMS.Infrastructure.Configuration.EntityFramework` (project reference, included as a dependency in NuGet package) + +Ensure your project targets .NET 10.0 or later. + +## License + +This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. \ No newline at end of file diff --git a/src/Configuration/FluentCMS.Infrastructure.Configuration.EntityFramework.Sqlite/README.md b/src/Configuration/FluentCMS.Infrastructure.Configuration.EntityFramework.Sqlite/README.md new file mode 100644 index 0000000..54fc991 --- /dev/null +++ b/src/Configuration/FluentCMS.Infrastructure.Configuration.EntityFramework.Sqlite/README.md @@ -0,0 +1,41 @@ +# FluentCMS.Infrastructure.Configuration.EntityFramework.Sqlite + +This package provides SQLite-specific Entity Framework configuration for the FluentCMS Infrastructure layer. It enables storing application configuration in an SQLite database using Entity Framework as the ORM, extending the base FluentCMS configuration capabilities to support SQLite as a lightweight, file-based database option. + +## Key Features + +- SQLite provider for storing and retrieving application configuration. +- Seamless integration with Entity Framework and the FluentCMS configuration system. +- Support for automatic configuration reloading based on a specified interval. + +## Installation + +Install this package via NuGet: + +```bash +dotnet add package FluentCMS.Infrastructure.Configuration.EntityFramework.Sqlite +``` + +## Usage + +To use SQLite for configuration storage, add the SQLite configuration provider to your configuration builder. Ensure you have the connection string defined in your appsettings.json or environment variables. + +```csharp +using FluentCMS.Infrastructure.Configuration.EntityFramework.Sqlite; + +var builder = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) + .AddSqliteConfiguration("DefaultConnection", TimeSpan.FromSeconds(30)); // Reload every 30 seconds +``` + +Make sure to register the required services and configure the database context as needed in your application. This extension method relies on the base Entity Framework configuration from `FluentCMS.Infrastructure.Configuration.EntityFramework`. + +## Dependencies + +- Microsoft.EntityFrameworkCore.Sqlite (latest stable version) +- FluentCMS.Infrastructure.Configuration.EntityFramework + +## License + +This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. \ No newline at end of file diff --git a/src/Configuration/FluentCMS.Infrastructure.Configuration.EntityFramework/README.md b/src/Configuration/FluentCMS.Infrastructure.Configuration.EntityFramework/README.md new file mode 100644 index 0000000..1b76463 --- /dev/null +++ b/src/Configuration/FluentCMS.Infrastructure.Configuration.EntityFramework/README.md @@ -0,0 +1,61 @@ +# FluentCMS.Infrastructure.Configuration.EntityFramework + +## Description + +This package provides Entity Framework-based configuration storage for FluentCMS Infrastructure. It allows storing and retrieving application configuration data dynamically from a database, enabling runtime configuration updates without application restarts. + +## Key Features + +- **EF-backed Configuration**: Store and manage configuration settings in a database using Entity Framework Core. +- **Automatic Caching**: In-memory caching for improved performance. +- **Periodic Reload**: Configurable automatic reloading of configuration from the database. +- **JSON Deserialization**: Supports nested JSON structures, flattened into key-value pairs for .NET configuration providers. +- **Data Seeding**: Includes data seeders for initializing configuration data. + +## Installation + +Install the package via NuGet: + +```bash +dotnet add package FluentCMS.Infrastructure.Configuration.EntityFramework +``` + +## Basic Usage + +To set up Entity Framework-based configuration in your application, follow these steps: + +1. Configure the service in `Program.cs` or your startup code: + +```csharp +using FluentCMS.Infrastructure.Configuration.EntityFramework; + +// In your Program.cs or Startup.cs +builder.Configuration.AddDatabaseConfiguration(options => +{ + options.UseSqlite("Data Source=configurations.db"); // or other EF provider + options.ReloadOnChange = TimeSpan.FromMinutes(5); // optional auto-reload +}); + +// For database migration/seeding +builder.Services.AddFluentCmsInfrastructure(options => +{ + options.AddDatabaseConfiguration(); +}); +``` + +2. The configuration will be loaded from the database and flattened for use with `IConfiguration`. + +Note: Ensure the database is created and seeded appropriately using the provided migrations and seeders. + +## Dependencies + +- Microsoft.Extensions.Configuration (10.0.2) +- Microsoft.Extensions.Configuration.EnvironmentVariables (10.0.2) +- Microsoft.Extensions.Configuration.Json (10.0.2) +- Microsoft.EntityFrameworkCore.Sqlite (10.0.2) +- FluentCMS.Infrastructure.Repositories.EntityFramework +- FluentCMS.Infrastructure.Configuration + +## License + +This project is licensed under the MIT License. \ No newline at end of file diff --git a/src/Configuration/FluentCMS.Infrastructure.Configuration/README.md b/src/Configuration/FluentCMS.Infrastructure.Configuration/README.md new file mode 100644 index 0000000..8fbc151 --- /dev/null +++ b/src/Configuration/FluentCMS.Infrastructure.Configuration/README.md @@ -0,0 +1,91 @@ +# FluentCMS Infrastructure Configuration + +## Overview + +FluentCMS Infrastructure Configuration provides a robust solution for managing configuration settings in FluentCMS applications. This library enables database-backed configuration options, allowing dynamic storage and retrieval of application settings through the ASP.NET Core Options pattern. It integrates seamlessly with configuration repositories to persist settings in the database, facilitating flexible and scalable configuration management. + +## Key Features + +- **Database-Backed Options**: Store and manage configuration options in a database using the ASP.NET Core Options pattern. +- **Dynamic Configuration Management**: Register configuration sections for database storage and bind them to configuration sources. +- **Thread-Safe Registry**: Singleton registry ensures thread-safe access and prevents duplicate registrations. +- **Extension Methods**: Fluent API for registering options classes with optional configuration binding. + +## Installation + +Install the NuGet package: + +```bash +dotnet add package FluentCMS.Infrastructure.Configuration +``` + +## Usage + +### Basic Setup + +First, add the database configuration registry to your services: + +```csharp +using FluentCMS.Infrastructure.Configuration; + +var builder = WebApplication.CreateBuilder(args); + +// Register the database configuration registry +builder.Services.AddDatabaseConfigurationRegistry(); + +// Optional: Add your configuration repository dependency +// builder.Services.AddScoped(); +``` + +### Configuring Options + +Register options classes for database storage: + +```csharp +// Register options class for database storage without binding +builder.Services.AddDbOptions("MySection"); + +// Register and bind to configuration section +builder.Services.AddDbOptions("MySection", builder.Configuration); + +// With custom binder options +builder.Services.AddDbOptions("MySection", builder.Configuration, binderOptions => +{ + binderOptions.BindNonPublicProperties = false; + // Configure other binder options as needed +}); +``` + +### Example Options Class + +```csharp +public class MyOptions +{ + public string Setting1 { get; set; } = string.Empty; + public int Setting2 { get; set; } +} +``` + +### Using Options + +Inject and use the configured options in your services: + +```csharp +public class MyService(IOptions options) +{ + private readonly MyOptions _options = options.Value; + + public void DoSomething() + { + Console.WriteLine(_options.Setting1); + } +} +``` + +## Dependencies + +- Microsoft.Extensions.Options.ConfigurationExtensions (10.0.2) + +## License + +This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. \ No newline at end of file diff --git a/src/EventBus/FluentCMS.Infrastructure.EventBus.Example/README.md b/src/EventBus/FluentCMS.Infrastructure.EventBus.Example/README.md index 36ca487..ad69163 100644 --- a/src/EventBus/FluentCMS.Infrastructure.EventBus.Example/README.md +++ b/src/EventBus/FluentCMS.Infrastructure.EventBus.Example/README.md @@ -1,103 +1,37 @@ -# FluentCMS EventBus - Example Application +# FluentCMS.Infrastructure.EventBus.Example -This example application demonstrates how to use the FluentCMS EventBus system in a real-world scenario. +## Description +This project provides an example of using the EventBus for FluentCMS Infrastructure. It demonstrates event publishing and handling with sample implementations for UserRegisteredEvent and OrderPlacedEvent. -## Features Demonstrated - -### 1. Event Publishing -- **UserRegisteredEvent**: Demonstrates handling user registration with multiple handlers -- **OrderPlacedEvent**: Shows order processing with concurrent handlers - -### 2. Multiple Event Handlers -Each event can have multiple handlers that execute independently: -- **User Registration**: - - `SendWelcomeEmailHandler` - Sends welcome email to new users - - `CreateUserProfileHandler` - Creates user profile in database - - `LogUserActivityHandler` - Logs user activity for audit - -- **Order Processing**: - - `UpdateInventoryHandler` - Updates inventory levels - - `SendOrderConfirmationHandler` - Sends order confirmation email - -### 3. Execution Modes - -#### Aggregate Mode (Default) -- Handlers execute **concurrently** for better performance -- All handlers complete even if some fail -- Exceptions are collected and thrown as `EventPublisherAggregatedException` - -#### FailFast Mode -- Handlers execute **sequentially** in registration order -- Execution stops immediately on first error -- Useful when handler order matters or for debugging - -## Running the Example +## Key Features +- Sample event handlers (SendOrderConfirmation, UpdateInventory for OrderPlacedEvent; CreateUserProfile, LogUserActivity, SendWelcomeEmail for UserRegisteredEvent) +- Event bus modes: Aggregate and FailFast +- Dependency injection setup with logging +- Performance measurement +## Installation ```bash -cd FluentCMS.Infrastructure.EventBus.Example -dotnet run -``` - -## Code Examples - -### Configuring Aggregate Mode (Default) -```csharp -services.AddInMemoryEventBus(options => -{ - options.Mode = EventPublisherOptions.ErrorHandlingMode.Aggregate; -}); +dotnet add package FluentCMS.Infrastructure.EventBus.Example ``` -### Configuring FailFast Mode +## Usage ```csharp -services.AddInMemoryEventBus(options => -{ - options.Mode = EventPublisherOptions.ErrorHandlingMode.FailFast; -}); -``` - -### Registering Event Handlers -```csharp -services.AddEventHandler(); -services.AddEventHandler(); -services.AddEventHandler(); -``` +var serviceProvider = new ServiceCollection() + .AddEventBusInMemory() + .AddLogging() + .AddEventHandlersFromAssembly(typeof(Program).Assembly) + .BuildServiceProvider(); -### Publishing Events -```csharp -var userEvent = new UserRegisteredEvent -{ - UserId = "USER-001", - Email = "john.doe@example.com", - FullName = "John Doe" -}; +var eventBus = serviceProvider.GetRequiredService(); -await publisher.Publish(userEvent); +// Publish event +await eventBus.PublishAsync(new OrderPlacedEvent { OrderId = "123", CustomerId = "456", TotalAmount = 99.99m, ItemCount = 1 }); ``` -## Key Concepts - -1. **Events inherit from EventBase** which provides: - - `EventId` - Unique identifier for each event instance - - `OccurredAt` - Timestamp when event was created - -2. **Handlers implement IEventSubscriber**: - - Scoped lifetime by default - - Support async operations - - Respect cancellation tokens - -3. **Automatic Dependency Injection**: - - Handlers can inject services via constructor - - Examples use `ILogger` for demonstration - -4. **Error Handling**: - - Aggregate mode: Continue executing all handlers, collect errors - - FailFast mode: Stop on first error for immediate feedback - -## Performance Comparison - -Based on the example output, you'll see: -- **Concurrent execution** (Aggregate mode): ~120ms for 3 handlers -- **Sequential execution** (FailFast mode): ~180ms for 3 handlers +## Dependencies +- EventBus abstractions: FluentCMS.Infrastructure.EventBus, FluentCMS.Infrastructure.EventBus.InMemory +- Microsoft.Extensions.DependencyInjection (10.0.2) +- Microsoft.Extensions.Logging.Console (10.0.2) -Concurrent execution is faster because handlers run in parallel! +## License +MIT diff --git a/src/EventBus/FluentCMS.Infrastructure.EventBus.InMemory/README.md b/src/EventBus/FluentCMS.Infrastructure.EventBus.InMemory/README.md index 2cc0858..d7dbf9a 100644 --- a/src/EventBus/FluentCMS.Infrastructure.EventBus.InMemory/README.md +++ b/src/EventBus/FluentCMS.Infrastructure.EventBus.InMemory/README.md @@ -1,186 +1,72 @@ -# FluentCMS.EventBus.InMemory - -**In-memory event bus implementation for FluentCMS, built for .NET 9.** - -## Overview - -`FluentCMS.EventBus.InMemory` is a lightweight, high-performance event bus for .NET applications. It enables decoupled communication between components using the publish/subscribe pattern, making it ideal for development, testing, and single-instance production scenarios. - -- **Publish/Subscribe** pattern for domain events -- **Dependency Injection**-friendly -- **Configurable error handling** (fail-fast or aggregate) -- **Automatic scope management** for event handlers -- **Detailed logging** for diagnostics - -## Table of Contents -- [Getting Started](#getting-started) - - [Installation](#installation) -- [Registration](#registration) -- [Usage](#usage) - - [Define an Event](#define-an-event) - - [Create a Subscriber](#create-a-subscriber) - - [Register a Subscriber](#register-a-subscriber) - - [Publish an Event](#publish-an-event) -- [Configuration](#configuration) -- [Logging](#logging) -- [Best Practices](#best-practices) -- [Extending](#extending) -- [Contributing](#contributing) -- [License](#license) - -## Getting Started - -### Prerequisites -- [.NET 9 SDK](https://dotnet.microsoft.com/download/dotnet/9.0) -- Reference to `FluentCMS.EventBus.Abstractions` +# FluentCMS.Infrastructure.EventBus.InMemory -## Installation - -Add the project or NuGet package to your solution: +An in-memory event bus implementation for FluentCMS Infrastructure, designed for fast, in-process event handling. -```sh -dotnet add package FluentCMS.EventBus.InMemory -``` +## Features -## Registration +- **Fast and efficient**: Provides low-latency event handling entirely within the process. +- **Multiple handlers support**: Allows multiple handlers per event type. +- **Error aggregation**: Aggregates exceptions from multiple handlers for better error management. +- **Configurable options**: Supports different error handling modes. -Register the in-memory event bus in your DI container (typically in `Startup.cs` or your service configuration): +## Installation -```csharp -using FluentCMS.EventBus.InMemory; +Install the package from NuGet: -builder.Services.AddInMemoryEventBus(options => -{ - options.Mode = EventPublisherOptions.ErrorHandlingMode.Aggregate; // or FailFast -}); ``` - -## Usage - -### Define an Event - -```csharp -public class UserRegisteredEvent : IEvent -{ - public string UserId { get; set; } -} +dotnet add package FluentCMS.Infrastructure.EventBus.InMemory ``` -### Create a Subscriber - -```csharp -public class SendWelcomeEmailSubscriber : IEventSubscriber -{ - public Task Handle(UserRegisteredEvent @event, CancellationToken cancellationToken) - { - // Example: Send a welcome email to the user - Console.WriteLine($"Welcome email sent to user {@event.UserId}"); - return Task.CompletedTask; - } -} -``` +## Usage -### Register a Subscriber +1. Register the event bus in your dependency injection container: ```csharp -services.AddScoped, SendWelcomeEmailSubscriber>(); +services.AddInMemoryEventBus(); ``` -### Publish an Event +2. Publish events using the `IEventPublisher` interface: ```csharp -public class UserService +public class SomeService { private readonly IEventPublisher _eventPublisher; - public UserService(IEventPublisher eventPublisher) + public SomeService(IEventPublisher eventPublisher) { _eventPublisher = eventPublisher; } - public async Task RegisterUserAsync(string userId) + public async Task PublishEvent() { - // Registration logic... - await _eventPublisher.Publish(new UserRegisteredEvent { UserId = userId }); + var @event = new SampleEvent(); + await _eventPublisher.PublishAsync(@event); } } ``` -## Configuration - -You can configure error handling mode via `EventPublisherOptions`: - -- `FailFast`: Stops on the first handler exception. -- `Aggregate` (default): Runs all handlers, aggregates exceptions, and throws at the end. - -```csharp -services.AddInMemoryEventBus(options => -{ - options.Mode = EventPublisherOptions.ErrorHandlingMode.FailFast; -}); -``` - -## Error Handling & Execution Behavior - -### FailFast Mode -- **Execution:** Handlers run **sequentially** in registration order -- **On Error:** Stops immediately when first handler throws -- **Use Case:** When you need guaranteed execution order and want to fail fast - -```csharp -services.AddInMemoryEventBus(options => -{ - options.Mode = EventPublisherOptions.ErrorHandlingMode.FailFast; -}); -``` - -### Aggregate Mode (Default) -- **Execution:** Handlers run **concurrently** using Task.WhenAll -- **On Error:** All handlers complete, then throws aggregate exception -- **Use Case:** Best performance when handlers are independent +3. Implement event handlers by inheriting from `IEventHandler`: ```csharp -services.AddInMemoryEventBus(options => +public class SampleEventHandler : IEventHandler { - options.Mode = EventPublisherOptions.ErrorHandlingMode.Aggregate; -}); + public async Task HandleEventAsync(SampleEvent @event) + { + // Handle the event + } +} ``` -### Thread Safety Considerations -⚠️ **Important:** In Aggregate mode, handlers execute concurrently. Ensure your handlers: -- Don't share mutable state -- Are thread-safe if they access shared resources -- Don't depend on execution order - -For ordered execution, use FailFast mode or implement coordination in handlers. - -## Logging - -- **Information**: Successful event publishing, including event type and subscriber count. -- **Warning**: No subscribers found for an event. -- **Error**: Handler exceptions, with detailed context. -- **Debug**: Scope management and context usage. - -## Best Practices +Handlers are automatically resolved and invoked by the event publisher. -- Use the in-memory event bus for development, testing, or single-instance production scenarios. -- For distributed or multi-instance deployments, consider a persistent or message-queue-based event bus. -- Register event subscribers with appropriate lifetimes (scoped, transient, or singleton as needed). -- Use meaningful event and subscriber names for clarity and maintainability. -- Handle exceptions in subscribers responsibly; avoid long-running or blocking operations in event handlers. +## Dependencies -## Extending - -You can extend or customize the event bus by implementing your own `IEventPublisher` or `IEventSubscriber`. - -## Contributing - -Contributions are welcome! Please open issues or submit pull requests for improvements or bug fixes. +- **EventBus abstractions**: `FluentCMS.Infrastructure.EventBus` +- **Framework**: + - `Microsoft.AspNetCore.Http` (2.3.9) + - `Microsoft.Extensions.Logging.Abstractions` (10.0.2) + - `Microsoft.Extensions.Options` (10.0.2) ## License -MIT License - ---- - -**FluentCMS.EventBus.InMemory** is part of the [FluentCMS](https://github.com/fluentcms/FluentCMS) ecosystem. +This project is licensed under the [MIT License](https://opensource.org/licenses/MIT). \ No newline at end of file diff --git a/src/EventBus/FluentCMS.Infrastructure.EventBus.Tests/README.md b/src/EventBus/FluentCMS.Infrastructure.EventBus.Tests/README.md index 2e01866..d1b49c0 100644 --- a/src/EventBus/FluentCMS.Infrastructure.EventBus.Tests/README.md +++ b/src/EventBus/FluentCMS.Infrastructure.EventBus.Tests/README.md @@ -1,146 +1,39 @@ -# FluentCMS EventBus - Test Suite +# FluentCMS.Infrastructure.EventBus.Tests -Comprehensive test suite with **100% code coverage** for the FluentCMS EventBus infrastructure. +> Test suite for the EventBus components in FluentCMS infrastructure, providing comprehensive unit tests to ensure reliable event publishing, handling, and service configurations. -## Test Statistics +## 📖 About +This package contains unit tests for the EventBus infrastructure in FluentCMS. It includes tests for event publishing, event handlers, service collection extensions, and various event bus implementations such as the in-memory provider. These tests are designed to validate the functionality and reliability of the EventBus system. -- **Total Tests**: 45 -- **Test Coverage**: 100% -- **All Tests Passing**: ✅ +**Note:** This package is intended for testing and development purposes only. It is not meant for production use. -## Test Organization +## 🚀 Installation -### Core Tests (`EventBase` & Service Registration) +Install the package via NuGet: -#### EventBaseTests (6 tests) -- ✅ Constructor sets OccurredAt timestamp -- ✅ Constructor sets unique EventId -- ✅ Generates unique EventIds for each instance -- ✅ Implements IEvent interface -- ✅ Properties are init-only -- ✅ Supports derived events - -#### ServiceCollectionExtensionsTests (5 tests) -- ✅ Throws ArgumentNullException when services is null -- ✅ Registers handlers as Scoped lifetime -- ✅ Returns ServiceCollection for fluent chaining -- ✅ Allows multiple handlers for same event -- ✅ Resolves handlers from service provider - -### InMemory Implementation Tests - -#### EventPublisherTests (11 tests) -- ✅ Throws ArgumentNullException when event is null -- ✅ Throws OperationCanceledException when cancelled -- ✅ Invokes single subscriber -- ✅ Invokes all subscribers for an event -- ✅ FailFast mode stops on first exception -- ✅ Aggregate mode collects all exceptions -- ✅ Uses HttpContext when available -- ✅ Executes sequentially in FailFast mode -- ✅ Executes concurrently in Aggregate mode -- ✅ Passes event data to handlers -- ✅ Passes cancellation token to handlers - -#### EventPublisherOptionsTests (6 tests) -- ✅ Default mode is Aggregate -- ✅ Can set mode to FailFast -- ✅ Can set mode to Aggregate -- ✅ ErrorHandlingMode has two values -- ✅ FailFast has value 0 -- ✅ Aggregate has value 1 - -#### EventPublisherAggregatedExceptionTests (7 tests) -- ✅ Sets inner exceptions correctly -- ✅ Sets event type property -- ✅ Sets message with event type name -- ✅ Is assignable to AggregateException -- ✅ Handles multiple exceptions -- ✅ Works with empty exception collection -- ✅ Preserves stack trace of inner exceptions - -#### ServiceCollectionExtensionsTests (10 tests) -- ✅ Throws ArgumentNullException when services is null -- ✅ Registers EventPublisher as Singleton -- ✅ Registers HttpContextAccessor -- ✅ Configures options with default settings -- ✅ Configures options with custom settings -- ✅ Returns ServiceCollection for fluent chaining -- ✅ Allows fluent configuration -- ✅ Prevents duplicate publisher registration -- ✅ Resolves EventPublisher correctly -- ✅ Uses defaults with null configuration - -## Running Tests - -### Run all tests -```bash -dotnet test FluentCMS.Infrastructure.EventBus.Tests -``` - -### Run with detailed output -```bash -dotnet test FluentCMS.Infrastructure.EventBus.Tests --logger "console;verbosity=detailed" -``` - -### Run with code coverage ```bash -dotnet test FluentCMS.Infrastructure.EventBus.Tests --collect:"XPlat Code Coverage" +dotnet add package FluentCMS.Infrastructure.EventBus.Tests ``` -## Test Frameworks & Libraries - -- **xUnit** v2.9.2 - Test framework -- **FluentAssertions** v6.12.0 - Assertion library -- **Moq** v4.20.72 - Mocking framework -- **Coverlet** v6.0.2 - Code coverage - -## Key Testing Patterns - -### 1. Dependency Injection Testing -Tests use real ServiceCollection and ServiceProvider to verify DI registration: -```csharp -var services = new ServiceCollection(); -services.AddInMemoryEventBus(); -var provider = services.BuildServiceProvider(); -var publisher = provider.GetRequiredService(); -``` - -### 2. Behavior Testing -Tests verify both success and failure scenarios: -```csharp -// Success scenario -await publisher.Publish(event); -handlerCalled.Should().BeTrue(); - -// Failure scenario -var act = async () => await publisher.Publish(null!); -await act.Should().ThrowAsync(); -``` - -### 3. Concurrency Testing -Tests verify sequential vs concurrent execution: -```csharp -// Sequential (FailFast mode) -executionOrder.Should().Equal(new[] { 1, 2 }); - -// Concurrent (Aggregate mode) -handler1Started.Should().BeTrue(); -handler2Started.Should().BeTrue(); -``` - -## Code Coverage - -All production code paths are covered including: -- ✅ Event creation and properties -- ✅ Service registration and configuration -- ✅ Event publishing with both modes -- ✅ Error handling (FailFast & Aggregate) -- ✅ Scope management (HTTP context & new scope) -- ✅ Cancellation token support -- ✅ Logging integration -- ✅ Exception handling and aggregation - -## Continuous Integration - -These tests are designed to run in CI/CD pipelines and provide fast, reliable feedback on code changes. +## 🛠 Key Features +- Unit tests for the `EventBase` class, ensuring proper event ID generation and property initialization. +- Tests for `ServiceCollectionExtensions`, verifying event handler registration and DI integration. +- Coverage for in-memory event publishing, including subscriber invocation, error handling modes, and aggregated exceptions. +- Comprehensive test coverage using xUnit, FluentAssertions, and Moq for mocking. + +## 📚 Dependencies +This test suite relies on the following key dependencies: +- .NET 10.0 +- xunit.v3 (3.2.2) +- FluentAssertions (8.8.0) +- Moq (4.20.72) +- Microsoft.NET.Test.Sdk (18.0.1) +- xunit.runner.visualstudio (3.1.5) +- coverlet.collector (6.0.4) +- Microsoft.Extensions.DependencyInjection (10.0.2) +- Microsoft.Extensions.Logging (10.0.2) + +Note: The package also has project references to the main EventBus and InMemory components for testing. + +## 📜 License +This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. \ No newline at end of file diff --git a/src/EventBus/FluentCMS.Infrastructure.EventBus/README.md b/src/EventBus/FluentCMS.Infrastructure.EventBus/README.md index 09b4838..11a96ea 100644 --- a/src/EventBus/FluentCMS.Infrastructure.EventBus/README.md +++ b/src/EventBus/FluentCMS.Infrastructure.EventBus/README.md @@ -1,126 +1,92 @@ -# FluentCMS.EventBus.Abstractions +# FluentCMS.Infrastructure.EventBus -**Event bus abstractions for FluentCMS, targeting .NET 9.** +Event-driven communication abstractions for FluentCMS Infrastructure. -## Overview +## Description -`FluentCMS.EventBus.Abstractions` provides the core interfaces and base types for implementing event-driven architectures in .NET applications. It defines the contracts for events, event publishers, and event subscribers, enabling decoupled communication between components using the publish/subscribe pattern. +FluentCMS Infrastructure EventBus provides a set of abstractions and utilities for implementing event-driven communication between components in the FluentCMS ecosystem. It includes base classes and interfaces for domain events, their publication, and subscription, facilitating a decoupled architecture. -- **IEvent**: Marker interface for domain events, with timestamp and unique ID -- **IEventPublisher**: Interface for publishing events to subscribers -- **IEventSubscriber**: Interface for handling events -- **EventBase**: Abstract base class for events with sensible defaults -- **DI Extensions**: Helper for registering event handlers +## Key Features -## Table of Contents -- [Getting Started](#getting-started) -- [Interfaces & Base Classes](#interfaces--base-classes) -- [Dependency Injection](#dependency-injection) -- [Usage Example](#usage-example) -- [Best Practices](#best-practices) -- [Extending](#extending) -- [Contributing](#contributing) -- [License](#license) +- `IEvent`: Marker interface for domain events, including properties for occurrence time and unique event ID. +- `EventBase`: Abstract base class for domain events that provides default implementations for common properties. +- `IEventSubscriber`: Interface for creating event handlers that respond to specific event types. +- `IEventPublisher`: Interface for publishing domain events to all registered subscribers. +- Dependency Injection extensions: `ServiceCollectionExtensions.AddEventHandler()` for registering event handlers in the service collection. -## Getting Started +## Installation -### Prerequisites -- [.NET 9 SDK](https://dotnet.microsoft.com/download/dotnet/9.0) +Install via NuGet: -Add a reference to this project or package in your solution: - -```sh -dotnet add package FluentCMS.EventBus.Abstractions +```bash +dotnet add package FluentCMS.Infrastructure.EventBus --version 1.0.0 ``` -## Interfaces & Base Classes +*Replace `1.0.0` with the desired version.* -### IEvent -```csharp -public interface IEvent -{ - DateTimeOffset OccurredAt { get; } - Guid EventId { get; } -} -``` +## Basic Usage -### EventBase -```csharp -public abstract class EventBase : IEvent -{ - public DateTimeOffset OccurredAt { get; init; } - public Guid EventId { get; init; } - protected EventBase() { /* ... */ } -} -``` +### Defining an Event + +Create a class that inherits from `EventBase`: -### IEventPublisher ```csharp -public interface IEventPublisher +using FluentCMS.Infrastructure.EventBus; + +public class UserCreatedEvent : EventBase { - Task Publish(TEvent data, CancellationToken cancellationToken = default) where TEvent : class, IEvent; + public Guid UserId { get; init; } + public string UserName { get; init; } } ``` -### IEventSubscriber +### Creating an Event Handler + +Implement the `IEventSubscriber` interface: + ```csharp -public interface IEventSubscriber where TEvent : class, IEvent +using FluentCMS.Infrastructure.EventBus.Abstractions; + +public class UserCreatedHandler : IEventSubscriber { - Task Handle(TEvent domainEvent, CancellationToken cancellationToken = default); + public Task Handle(UserCreatedEvent domainEvent, CancellationToken cancellationToken = default) + { + // Handle the event, e.g., send email + Console.WriteLine($"User {domainEvent.UserName} created."); + return Task.CompletedTask; + } } ``` -## Dependency Injection +### Registering the Handler -Register event handlers using the provided extension: +Register the event handler using the extension method in your dependency injection setup (e.g., `Program.cs` or `Startup.cs`): ```csharp -services.AddEventHandler(); +using FluentCMS.Infrastructure.EventBus; + +services.AddEventHandler(); ``` -This registers `SendWelcomeEmailSubscriber` as a scoped handler for `UserRegisteredEvent`. +### Publishing an Event -## Usage Example +Inject and use the `IEventPublisher` to publish events (note: an implementation of `IEventPublisher` must be provided separately): ```csharp -// Define an event -global using FluentCMS.EventBus.Abstractions; +using FluentCMS.Infrastructure.EventBus.Abstractions; -public class UserRegisteredEvent : EventBase { public string UserId { get; set; } } - -// Implement a subscriber -public class SendWelcomeEmailSubscriber : IEventSubscriber +// Assume _eventPublisher is injected (e.g., via constructor) +await _eventPublisher.Publish(new UserCreatedEvent { - public Task Handle(UserRegisteredEvent @event, CancellationToken cancellationToken) - { - // Send welcome email logic - return Task.CompletedTask; - } -} - -// Register the handler -services.AddEventHandler(); - -// Publish an event (implementation required) -await eventPublisher.Publish(new UserRegisteredEvent { UserId = "123" }); + UserId = Guid.NewGuid(), + UserName = "JohnDoe" +}); ``` -## Best Practices -- Use `EventBase` for consistent event metadata. -- Register handlers with appropriate lifetimes (scoped by default). -- Keep event handlers focused and non-blocking. -- Use unique event types for different domain actions. - -## Extending -- Implement custom event publishers or subscribers as needed. -- Extend `EventBase` for additional metadata. +## Dependencies -## Contributing -Contributions are welcome! Please open issues or submit pull requests for improvements or bug fixes. +- `Microsoft.Extensions.DependencyInjection.Abstractions` (>= 10.0.2) ## License -MIT License - ---- -**FluentCMS.EventBus.Abstractions** is part of the [FluentCMS](https://github.com/fluentcms/FluentCMS) ecosystem. +This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. \ No newline at end of file diff --git a/src/Logging/FluentCMS.Infrastructure.Logging/README.md b/src/Logging/FluentCMS.Infrastructure.Logging/README.md new file mode 100644 index 0000000..1906952 --- /dev/null +++ b/src/Logging/FluentCMS.Infrastructure.Logging/README.md @@ -0,0 +1,50 @@ +# FluentCMS.Infrastructure.Logging + +A logging infrastructure library for FluentCMS applications, utilizing Serilog for efficient and structured logging. + +## Features + +- Structured logging with log levels and contextual information. +- Seamless integration with ASP.NET Core applications. + +## Installation + +To install the package, run the following command in your .NET project: + +```bash +dotnet add package FluentCMS.Infrastructure.Logging +``` + +## Usage + +Add the logging configuration to your application's startup (e.g., in `Program.cs`): + +```csharp +using FluentCMS.Infrastructure.Logging; +using Serilog; + +var builder = WebApplication.CreateBuilder(args); + +// Configure Serilog +builder.Host.UseSerilog((context, loggerConfiguration) => +{ + loggerConfiguration + .ReadFrom.Configuration(context.Configuration) + .Enrich.FromLogContext() + .WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}") + .WriteTo.File("path/to/logfile.txt", rollingInterval: RollingInterval.Day); +}); + +// Build the app +var app = builder.Build(); +``` + +This sets up basic structured logging to console and a rolling file. + +## Dependencies + +- Serilog.AspNetCore (10.0.0) + +## License + +This project is licensed under the MIT License. \ No newline at end of file diff --git a/src/Logging/README.md b/src/Logging/README.md new file mode 100644 index 0000000..d49910c --- /dev/null +++ b/src/Logging/README.md @@ -0,0 +1,44 @@ +# Logging + +> Centralized logging module for FluentCMS using Serilog + +## 📖 About +This project provides a centralized logging infrastructure for the FluentCMS application. It uses Serilog to configure structured logging with output to the console and daily rolling log files, facilitating efficient monitoring, debugging, and troubleshooting of application behavior. + +## ✨ Key Features +- Structured logging with Serilog +- Console output for development +- Daily rolling log files for persistence +- Configurable minimum log levels (Debug, with override for Microsoft to Warning) +- Integration with .NET's dependency injection via ILoggerFactory + +## 🚀 Getting Started + +### Prerequisites +* .NET 8 or later + +### Installation +```bash +# Install dependencies +dotnet add package Serilog +dotnet add package Serilog.Extensions.Logging +dotnet add package Serilog.Console +dotnet add package Serilog.File +``` + +### Integration +In your application's `IHostBuilder` setup (e.g., in `Program.cs`): + +```csharp +using FluentCMS.Infrastructure.Logging; + +var builder = WebApplication.CreateBuilder(args); + +// Initialize the logger factory +var loggerFactory = builder.Host.InitLogFactory(); + +// Now you can use it for DI or pass to services +builder.Services.AddSingleton(loggerFactory); +``` + +Logs will be written to the console and to daily files in the `logs/` directory (e.g., `ourapp-2023-05-01.log`). \ No newline at end of file diff --git a/src/Plugins/FluentCMS.Infrastructure.Plugins.Abstractions/IPluginStartup.cs b/src/Plugins/FluentCMS.Infrastructure.Plugins.Abstractions/IPluginStartup.cs index 0414d8f..9afd4c2 100644 --- a/src/Plugins/FluentCMS.Infrastructure.Plugins.Abstractions/IPluginStartup.cs +++ b/src/Plugins/FluentCMS.Infrastructure.Plugins.Abstractions/IPluginStartup.cs @@ -10,9 +10,6 @@ namespace FluentCMS.Infrastructure.Plugins.Abstractions; /// public interface IPluginStartup { - /// - /// Gets the display name of the plugin. Defaults to the assembly name. - /// public virtual string Name => GetType().Assembly.GetName().Name ?? string.Empty; /// diff --git a/src/Plugins/FluentCMS.Infrastructure.Plugins.Abstractions/README.md b/src/Plugins/FluentCMS.Infrastructure.Plugins.Abstractions/README.md new file mode 100644 index 0000000..962ad72 --- /dev/null +++ b/src/Plugins/FluentCMS.Infrastructure.Plugins.Abstractions/README.md @@ -0,0 +1,49 @@ +# FluentCMS Infrastructure Plugins Abstractions + +This package provides the abstractions and interfaces for the plugin system in FluentCMS Infrastructure. It allows developers to create and manage plugins within the FluentCMS ecosystem. + +## Key Features + +- `IPluginStartup`: Interface for plugin startup classes, defining methods for configuring services and application pipeline. +- `PluginAttribute`: Attribute to mark classes as plugin startup entries for automatic discovery. + +## Installation + +Install the package via NuGet: + +```bash +dotnet add package FluentCMS.Infrastructure.Plugins.Abstractions +``` + +## Usage + +To create a plugin, implement the `IPluginStartup` interface and mark your class with the `Plugin` attribute. + +```csharp +using FluentCMS.Infrastructure.Plugins.Abstractions; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; + +[Plugin] // This attribute marks the class as a plugin +public class SamplePlugin : IPluginStartup +{ + public void ConfigureServices(IServiceCollection services, IConfiguration? configuration) + { + // Register services here + } + + public void Configure(IApplicationBuilder app) + { + // Configure middleware here + } +} +``` + +## Dependencies + +None external. + +## License + +MIT \ No newline at end of file diff --git a/src/Plugins/FluentCMS.Infrastructure.Plugins/README.md b/src/Plugins/FluentCMS.Infrastructure.Plugins/README.md new file mode 100644 index 0000000..fa0fb8c --- /dev/null +++ b/src/Plugins/FluentCMS.Infrastructure.Plugins/README.md @@ -0,0 +1,78 @@ +# FluentCMS.Infrastructure.Plugins + +A lightweight and extensible plugin system implementation for FluentCMS Infrastructure, enabling dynamic discovery, loading, and initialization of plugins in .NET applications. + +## Features + +- **Dynamic Plugin Loading**: Automatically scans and loads plugin assemblies at runtime. +- **Plugin Discovery**: Discovers plugins marked with custom attributes in specified directories. +- **Initialization Management**: Handles plugin initialization with error handling and logging. +- **Assembly Isolation**: Uses custom load contexts for plugin assemblies to prevent conflicts. +- **Configuration Options**: Flexible configuration through `PluginSystemOptions`. + +## Installation + +Install the package via NuGet: + +```bash +dotnet add package FluentCMS.Infrastructure.Plugins +``` + +## Usage + +### Basic Setup + +Add the plugin system to your services in `Program.cs`: + +```csharp +using FluentCMS.Infrastructure.Plugins; + +var builder = WebApplication.CreateBuilder(args); + +// Configure plugin system +builder.Services.AddPluginSystem(builder.Configuration, options => +{ + options.PluginDirectory = "path/to/plugins"; + // Additional configuration... +}); + +var app = builder.Build(); + +// Start plugin system +app.UsePluginSystem(); +``` + +### Creating a Plugin + +Implement the `IPluginStartup` interface in your plugin assembly: + +```csharp +using FluentCMS.Infrastructure.Plugins.Abstractions; + +[PluginAttribute] +public class MyPlugin : IPluginStartup +{ + public void ConfigureServices(IServiceCollection services, IConfiguration configuration) + { + // Add plugin services here + } + + public void Configure(IApplicationBuilder app) + { + // Configure the application pipeline here + } +} +``` + +Place your plugin assembly in the specified plugin directory, and it will be loaded automatically. + +## Dependencies + +- `Microsoft.Extensions.Logging.Abstractions` (Version 10.0.2) +- `System.Reflection.MetadataLoadContext` (Version 10.0.2) + +Target framework: .NET 10.0 + +## License + +This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. \ No newline at end of file diff --git a/src/Plugins/README.md b/src/Plugins/README.md new file mode 100644 index 0000000..b939e39 --- /dev/null +++ b/src/Plugins/README.md @@ -0,0 +1,34 @@ +# Plugins + +> A modular plugin system for FluentCMS infrastructure, enabling dynamic discovery, loading, and initialization of plugins to extend core functionality. + +## 📖 About +The `Plugins` project provides a flexible and robust plugin architecture for FluentCMS. It allows seamless discovery, loading, and management of plugins, enabling developers to extend the CMS capabilities dynamically. The system emphasizes modularity, safe loading of assemblies, and straightforward initialization, making it easy to build and integrate additional features. + +## 🚀 Getting Started + +### Prerequisites +* .NET 10.0 Runtime and SDK + +### Installation +Since this project is a library designed to be integrated within a larger application, include the relevant DLLs or package references into your main application. Ensure the plugin assemblies are placed in accessible directories for discovery. + +### Usage Example +```csharp +// Example of integrating the plugin system during application startup +var pluginDiscovery = new PluginDiscovery(); +var plugins = pluginDiscovery.Scan("path/to/plugin/directory"); +var pluginLoader = new PluginLoader(); +var loadedPlugins = plugins.Select(plugin => pluginLoader.Load(plugin)); +foreach (var plugin in loadedPlugins) +{ + // Initialize plugin +} +``` + +## 🔧 Features +- **Plugin Discovery**: Automatically scans directories for plugin assemblies. +- **Safe Loading**: Uses a custom AssemblyLoadContext for isolated and collectible plugin loading. +- **Dynamic Initialization**: Instantiates and initializes plugins implementing `IPluginStartup`. +- **Robust Error Handling**: Custom exceptions and logging support error diagnostics. +- **Extensible Architecture**: Based on interfaces, attributes, and abstraction for easy extension and customization. \ No newline at end of file diff --git a/src/Providers/FluentCMS.Infrastructure.Providers.Abstractions/README.md b/src/Providers/FluentCMS.Infrastructure.Providers.Abstractions/README.md index e8412a3..b84d732 100644 --- a/src/Providers/FluentCMS.Infrastructure.Providers.Abstractions/README.md +++ b/src/Providers/FluentCMS.Infrastructure.Providers.Abstractions/README.md @@ -1,503 +1,76 @@ -# FluentCMS.Providers.Abstractions +# FluentCMS.Infrastructure.Providers.Abstractions -The foundational abstractions and contracts for the FluentCMS provider system. This package contains the core interfaces, base classes, and contracts that all provider implementations must follow. +[![NuGet Version](https://img.shields.io/nuget/v/FluentCMS.Infrastructure.Providers.Abstractions)](https://www.nuget.org/packages/FluentCMS.Infrastructure.Providers.Abstractions/) -## Overview +## Description -This package defines the core abstractions that enable the pluggable provider architecture in FluentCMS. It provides the necessary interfaces and base classes for creating provider modules and implementing provider patterns. +FluentCMS Infrastructure Providers Abstractions provides fundamental abstractions and interfaces for implementing provider modules in the FluentCMS infrastructure. This library defines the core contracts and base classes that enable a consistent and extensible provider architecture within the FluentCMS ecosystem. -## Key Components +## Key Features -### Core Interfaces +- **IProvider**: Base marker interface that all provider implementations must inherit. +- **IProviderModule**: Defines the core interface for provider modules, including service configuration methods. +- **ProviderModuleBase**: Abstract base classes providing default implementations for provider modules, supporting both typed and untyped providers. +- Built on .NET 10.0 for modern asynchronous and dependency injection patterns. -#### IProvider -The base marker interface that all provider implementations must implement. +## Installation -```csharp -/// -/// Base marker interface for all providers. -/// All provider implementations must implement this interface. -/// -public interface IProvider -{ -} -``` - -**Usage:** -```csharp -public interface IEmailProvider : IProvider -{ - Task SendEmailAsync(string to, string subject, string body); -} - -public class SmtpProvider : IEmailProvider -{ - // Implementation -} -``` - -#### IProviderModule -Defines the contract for provider modules that register and configure providers. - -```csharp -public interface IProviderModule -{ - string Area { get; } - string DisplayName { get; } - Type ProviderType { get; } - Type? OptionsType { get; } - Type InterfaceType { get; } - void ConfigureServices(IServiceCollection services); -} -``` - -**Properties:** -- `Area`: The functional area this provider belongs to (e.g., "Email", "Storage") -- `DisplayName`: Human-readable name for administrative purposes -- `ProviderType`: The concrete provider implementation type -- `OptionsType`: Optional configuration options type -- `InterfaceType`: The service interface the provider implements -- `ConfigureServices`: Method to register additional services - -#### Generic Provider Module Interfaces - -```csharp -// For providers with options -public interface IProviderModule : IProviderModule - where TProvider : class, IProvider - where TOptions : class, new() -{ -} - -// For providers without options -public interface IProviderModule : IProviderModule - where TProvider : class, IProvider -{ -} -``` - -### Base Classes - -#### ProviderModuleBase -Base class for provider modules with configuration options. - -```csharp -public abstract class ProviderModuleBase : ProviderModuleBase - where TProvider : class, IProvider - where TOptions : class, new() -{ - public override Type? OptionsType => typeof(TOptions); -} -``` - -**Example Implementation:** -```csharp -public class SmtpProviderModule : ProviderModuleBase -{ - public override string Area => "Email"; - public override string DisplayName => "SMTP Email Provider"; - - public override void ConfigureServices(IServiceCollection services) - { - services.AddTransient(); - } -} -``` - -#### ProviderModuleBase -Base class for provider modules without configuration options. - -```csharp -public abstract class ProviderModuleBase : IProviderModule - where TProvider : class, IProvider -{ - public abstract string Area { get; } - public abstract string DisplayName { get; } - public Type ProviderType => typeof(TProvider); - public virtual Type? OptionsType => null; - - public virtual Type InterfaceType - { - get - { - var interfaces = typeof(TProvider).GetInterfaces() - .Where(i => i != typeof(IProvider) && typeof(IProvider).IsAssignableFrom(i)) - .ToArray(); - - if (interfaces.Length == 0) - throw new InvalidOperationException($"Provider {typeof(TProvider).Name} must implement at least one interface that extends IProvider."); - - return interfaces.First(); - } - } - - public virtual void ConfigureServices(IServiceCollection services) - { - // Default implementation does nothing - } -} -``` - -**Example Implementation:** -```csharp -public class ConsoleLoggerModule : ProviderModuleBase -{ - public override string Area => "Logging"; - public override string DisplayName => "Console Logger"; -} -``` - -## Creating Provider Implementations - -### Step 1: Define the Provider Interface - -```csharp -public interface IFileStorageProvider : IProvider -{ - Task SaveFileAsync(Stream fileStream, string fileName); - Task GetFileAsync(string fileId); - Task DeleteFileAsync(string fileId); - Task FileExistsAsync(string fileId); -} -``` - -### Step 2: Create Configuration Options (Optional) - -```csharp -public class LocalStorageOptions -{ - public string BasePath { get; set; } = "/var/storage"; - public long MaxFileSize { get; set; } = 10 * 1024 * 1024; // 10MB - public string[] AllowedExtensions { get; set; } = { ".jpg", ".png", ".pdf" }; -} -``` - -### Step 3: Implement the Provider - -```csharp -public class LocalFileStorageProvider : IFileStorageProvider -{ - private readonly LocalStorageOptions _options; - private readonly ILogger _logger; - - public LocalFileStorageProvider( - LocalStorageOptions options, - ILogger logger) - { - _options = options; - _logger = logger; - } - - public async Task SaveFileAsync(Stream fileStream, string fileName) - { - var fileId = Guid.NewGuid().ToString(); - var filePath = Path.Combine(_options.BasePath, fileId); - - using var fileOutput = File.Create(filePath); - await fileStream.CopyToAsync(fileOutput); - - _logger.LogInformation("File {FileName} saved as {FileId}", fileName, fileId); - return fileId; - } +Install the package via NuGet Package Manager: - public async Task GetFileAsync(string fileId) - { - var filePath = Path.Combine(_options.BasePath, fileId); - - if (!File.Exists(filePath)) - throw new FileNotFoundException($"File {fileId} not found"); - - return File.OpenRead(filePath); - } - - public async Task DeleteFileAsync(string fileId) - { - var filePath = Path.Combine(_options.BasePath, fileId); - - if (File.Exists(filePath)) - { - File.Delete(filePath); - _logger.LogInformation("File {FileId} deleted", fileId); - } - } - - public async Task FileExistsAsync(string fileId) - { - var filePath = Path.Combine(_options.BasePath, fileId); - return File.Exists(filePath); - } -} +```bash +dotnet add package FluentCMS.Infrastructure.Providers.Abstractions ``` -### Step 4: Create the Provider Module +## Basic Usage -```csharp -public class LocalFileStorageModule : ProviderModuleBase -{ - public override string Area => "FileStorage"; - public override string DisplayName => "Local File Storage Provider"; - - public override void ConfigureServices(IServiceCollection services) - { - // Register any additional services needed by the provider - services.AddTransient(); - } -} -``` - -## Advanced Patterns - -### Multiple Interface Implementation +To implement a custom provider, inherit from the provided interfaces and base classes: ```csharp -public interface ICacheProvider : IProvider -{ - Task SetAsync(string key, T value, TimeSpan? expiry = null); - Task GetAsync(string key); - Task RemoveAsync(string key); -} - -public interface IDistributedCacheProvider : ICacheProvider -{ - Task InvalidateAsync(string pattern); - Task> GetKeysAsync(string pattern); -} +using FluentCMS.Infrastructure.Providers.Abstractions; +using Microsoft.Extensions.DependencyInjection; -// Provider implementing multiple interfaces -public class RedisProvider : IDistributedCacheProvider +// Example provider interface +public interface IMyProvider : IProvider { - // Implementation + Task DoSomethingAsync(); } -// Module specifying the primary interface -public class RedisProviderModule : ProviderModuleBase +// Example provider implementation +public class MyProvider : IMyProvider { - public override string Area => "Cache"; - public override string DisplayName => "Redis Cache Provider"; - - // Override to specify the primary interface - public override Type InterfaceType => typeof(IDistributedCacheProvider); + public Task DoSomethingAsync() => Task.CompletedTask; } -``` -### Provider with Complex Dependencies - -```csharp -public class DatabaseEmailProvider : IEmailProvider +// Example provider module +public class MyProviderModule : ProviderModuleBase { - private readonly EmailOptions _options; - private readonly IDbContext _dbContext; - private readonly ITemplateEngine _templateEngine; - - public DatabaseEmailProvider( - EmailOptions options, - IDbContext dbContext, - ITemplateEngine templateEngine) + public override void ConfigureServices(IServiceCollection services, MyProviderOptions options) { - _options = options; - _dbContext = dbContext; - _templateEngine = templateEngine; + services.AddScoped(); } - - // Implementation } -public class DatabaseEmailModule : ProviderModuleBase +// Provider options +public class MyProviderOptions { - public override string Area => "Email"; - public override string DisplayName => "Database Email Provider"; - - public override void ConfigureServices(IServiceCollection services) - { - // Register dependencies - services.AddScoped(); - services.AddScoped(); - } + // Define your options here } ``` -### Provider with Validation +Integrate the provider module into your application by registering it with the dependency injection container: ```csharp -public class ValidatedOptions -{ - [Required] - public string ApiKey { get; set; } = string.Empty; - - [Range(1, 100)] - public int MaxRetries { get; set; } = 3; - - [Url] - public string BaseUrl { get; set; } = string.Empty; -} - -public class ValidatedProviderModule : ProviderModuleBase -{ - public override string Area => "External"; - public override string DisplayName => "External API Provider"; - - public override void ConfigureServices(IServiceCollection services) - { - // Add options validation - services.AddOptions() - .ValidateDataAnnotations() - .ValidateOnStart(); - } -} +var options = new MyProviderOptions(); +var module = new MyProviderModule(); +var services = new ServiceCollection(); +module.ConfigureServices(services, options); ``` -## Best Practices - -### 1. Interface Design -- Keep interfaces focused and cohesive -- Use async patterns for I/O operations -- Include cancellation token support -- Follow SOLID principles - -```csharp -public interface INotificationProvider : IProvider -{ - Task SendNotificationAsync( - string recipient, - string message, - NotificationOptions? options = null, - CancellationToken cancellationToken = default); - - Task CanSendToAsync( - string recipient, - CancellationToken cancellationToken = default); -} -``` - -### 2. Provider Implementation -- Make providers stateless when possible -- Use dependency injection for external dependencies -- Implement proper error handling and logging -- Consider thread safety requirements - -```csharp -public class EmailProvider : IEmailProvider -{ - private readonly EmailOptions _options; - private readonly ILogger _logger; - private readonly IHttpClientFactory _httpClientFactory; - - public EmailProvider( - EmailOptions options, - ILogger logger, - IHttpClientFactory httpClientFactory) - { - _options = options ?? throw new ArgumentNullException(nameof(options)); - _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - _httpClientFactory = httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory)); - } - - public async Task SendEmailAsync(string to, string subject, string body) - { - try - { - // Implementation with proper error handling - _logger.LogInformation("Sending email to {Recipient}", to); - // ... send logic - _logger.LogInformation("Email sent successfully to {Recipient}", to); - } - catch (Exception ex) - { - _logger.LogError(ex, "Failed to send email to {Recipient}", to); - throw; - } - } -} -``` - -### 3. Options Configuration -- Use data annotations for validation -- Provide sensible defaults -- Document configuration requirements - -```csharp -public class EmailOptions -{ - /// - /// SMTP server hostname or IP address - /// - [Required] - public string SmtpServer { get; set; } = string.Empty; - - /// - /// SMTP server port (default: 587 for TLS) - /// - [Range(1, 65535)] - public int Port { get; set; } = 587; - - /// - /// Enable SSL/TLS encryption - /// - public bool UseSsl { get; set; } = true; - - /// - /// Authentication username - /// - public string? Username { get; set; } - - /// - /// Authentication password - /// - public string? Password { get; set; } - - /// - /// Default sender email address - /// - [EmailAddress] - public string? DefaultSender { get; set; } - - /// - /// Connection timeout in seconds - /// - [Range(1, 300)] - public int TimeoutSeconds { get; set; } = 30; -} -``` - -### 4. Module Configuration -- Keep area names consistent and descriptive -- Provide clear display names -- Register necessary dependencies - -```csharp -public class EmailProviderModule : ProviderModuleBase -{ - public override string Area => "Email"; - public override string DisplayName => "SMTP Email Provider"; - - public override void ConfigureServices(IServiceCollection services) - { - // Register HTTP client for API calls - services.AddHttpClient(client => - { - client.Timeout = TimeSpan.FromSeconds(30); - }); - - // Register additional dependencies - services.AddTransient(); - services.AddTransient(); - } -} -``` - -## Package Dependencies - -This package has minimal dependencies to ensure broad compatibility: - -- Microsoft.Extensions.DependencyInjection.Abstractions - -## Version Compatibility +## Dependencies -- .NET 9.0+ -- Compatible with ASP.NET Core dependency injection -- Supports all Microsoft.Extensions.* packages +- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.2) +- .NET 10.0 -## See Also +## License -- [FluentCMS.Providers](../FluentCMS.Providers/README.md) - Core provider system implementation -- [FluentCMS.Providers.Repositories.EntityFramework](../FluentCMS.Providers.Repositories.EntityFramework/README.md) - Entity Framework provider repository +This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. \ No newline at end of file diff --git a/src/Providers/FluentCMS.Infrastructure.Providers.Repositories.EntityFramework/README.md b/src/Providers/FluentCMS.Infrastructure.Providers.Repositories.EntityFramework/README.md index 1b96cad..784b0a9 100644 --- a/src/Providers/FluentCMS.Infrastructure.Providers.Repositories.EntityFramework/README.md +++ b/src/Providers/FluentCMS.Infrastructure.Providers.Repositories.EntityFramework/README.md @@ -1,549 +1,33 @@ # FluentCMS.Providers.Repositories.EntityFramework -Entity Framework implementation of the provider repository for the FluentCMS provider system. This package provides database persistence for provider configurations using Entity Framework Core. - -## Overview - -This package implements the `IProviderRepository` interface using Entity Framework Core, enabling database-backed storage and management of provider configurations. It includes comprehensive data integrity constraints, transaction management, and performance optimizations. +Entity Framework repository providers for FluentCMS Infrastructure. ## Key Features -- **Database Persistence**: Store provider configurations in SQL databases -- **Data Integrity**: Unique constraints and validation rules -- **Transaction Management**: ACID compliance with automatic retry policies -- **Performance Optimized**: Efficient queries with proper indexing -- **Audit Support**: Built-in audit fields for tracking changes -- **Migration Support**: Entity Framework migrations for schema management - -## Components - -### ProviderDbContext -The Entity Framework DbContext for provider data. - -```csharp -public class ProviderDbContext : DbContext -{ - public DbSet Providers { get; set; } - - // Automatic audit field management - // Database constraints and indexes - // Error handling with meaningful messages -} -``` - -**Features:** -- Automatic audit field updates (CreatedAt, UpdatedAt) -- Database constraints for data integrity -- Optimized indexes for performance -- Meaningful error messages for constraint violations - -### ProviderRepository -Entity Framework implementation of `IProviderRepository`. - -```csharp -public class ProviderRepository : IProviderRepository, IDisposable -{ - Task AddMany(IEnumerable providers, CancellationToken cancellationToken = default); - Task Update(Provider provider, CancellationToken cancellationToken = default); - Task Remove(Provider provider, CancellationToken cancellationToken = default); - Task> GetAll(CancellationToken cancellationToken = default); - Task GetByAreaAndName(string area, string name, CancellationToken cancellationToken = default); - Task> GetByArea(string area, CancellationToken cancellationToken = default); -} -``` - -**Features:** -- Transaction management with retry policies -- Comprehensive validation -- Performance optimizations (AsNoTracking for reads) -- Proper error handling and logging -- Resource cleanup with IDisposable - -### Provider Entity -Enhanced provider entity with audit support. - -```csharp -public class Provider : AuditableEntity -{ - public string Name { get; set; } - public string DisplayName { get; set; } - public string Area { get; set; } - public string ModuleType { get; set; } - public bool IsActive { get; set; } - public string? Options { get; set; } - - // Inherited from AuditableEntity - public Guid Id { get; set; } - public DateTime CreatedAt { get; set; } - public DateTime UpdatedAt { get; set; } - public string? CreatedBy { get; set; } - public string? UpdatedBy { get; set; } -} -``` - -## Setup and Configuration - -### 1. Package Installation - -```bash -dotnet add package Microsoft.EntityFrameworkCore.SqlServer -# or your preferred EF Core provider -``` - -### 2. Service Registration - -```csharp -// Program.cs -services.AddDbContext(options => - options.UseSqlServer(connectionString)); - -services.AddProviders() - .UseEntityFramework(); -``` +- EF-based data access providers -### 3. Database Migration +## Installation ```bash -# Add migration -dotnet ef migrations add InitialCreate --context ProviderDbContext - -# Update database -dotnet ef database update --context ProviderDbContext -``` - -### 4. Connection String Configuration - -```json -{ - "ConnectionStrings": { - "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=FluentCMS;Trusted_Connection=true;MultipleActiveResultSets=true" - } -} -``` - -## Database Schema - -### Providers Table - -| Column | Type | Constraints | Description | -|--------|------|-------------|-------------| -| Id | uniqueidentifier | PK | Primary key | -| Name | nvarchar(100) | NOT NULL | Provider name | -| DisplayName | nvarchar(200) | NOT NULL | Display name | -| Area | nvarchar(50) | NOT NULL | Functional area | -| ModuleType | nvarchar(200) | NOT NULL | Module type name | -| IsActive | bit | NOT NULL, DEFAULT(0) | Active status | -| Options | nvarchar(4000) | NULL | JSON options | -| CreatedAt | datetime2 | NOT NULL, DEFAULT(GETUTCDATE()) | Creation timestamp | -| UpdatedAt | datetime2 | NOT NULL, DEFAULT(GETUTCDATE()) | Update timestamp | -| CreatedBy | nvarchar(255) | NULL | Created by user | -| UpdatedBy | nvarchar(255) | NULL | Updated by user | - -### Indexes - -```sql --- Performance indexes -CREATE INDEX IX_Provider_Area ON Providers (Area); -CREATE INDEX IX_Provider_ModuleType ON Providers (ModuleType); -CREATE INDEX IX_Provider_Area_IsActive ON Providers (Area, IsActive) WHERE IsActive = 1; - --- Unique constraints -CREATE UNIQUE INDEX UX_Provider_Area_Name ON Providers (Area, Name); -``` - -### Check Constraints - -```sql --- Ensure only one active provider per area (SQL Server) -ALTER TABLE Providers ADD CONSTRAINT CK_Provider_SingleActivePerArea -CHECK (IsActive = 0 OR NOT EXISTS ( - SELECT 1 FROM Providers p2 - WHERE p2.Area = Area AND p2.IsActive = 1 AND p2.Id != Id -)); -``` - -## Usage Examples - -### Basic Operations - -```csharp -public class ProviderManagementService -{ - private readonly IProviderRepository _repository; - private readonly ILogger _logger; - - public ProviderManagementService( - IProviderRepository repository, - ILogger logger) - { - _repository = repository; - _logger = logger; - } - - public async Task CreateProviderAsync(string area, string name, string moduleType, object? options = null) - { - var provider = new Provider - { - Area = area, - Name = name, - DisplayName = name, - ModuleType = moduleType, - IsActive = false, - Options = options != null ? JsonSerializer.Serialize(options) : null - }; - - await _repository.AddMany([provider]); - _logger.LogInformation("Created provider {Name} in area {Area}", name, area); - - return provider; - } - - public async Task ActivateProviderAsync(string area, string name) - { - // Deactivate all providers in the area - var existingProviders = await _repository.GetByArea(area); - foreach (var provider in existingProviders.Where(p => p.IsActive)) - { - provider.IsActive = false; - await _repository.Update(provider); - } - - // Activate the specified provider - var targetProvider = await _repository.GetByAreaAndName(area, name); - if (targetProvider == null) - throw new InvalidOperationException($"Provider {name} not found in area {area}"); - - targetProvider.IsActive = true; - await _repository.Update(targetProvider); - - _logger.LogInformation("Activated provider {Name} in area {Area}", name, area); - } -} -``` - -### Advanced Queries - -```csharp -public class ProviderAnalyticsService -{ - private readonly ProviderDbContext _context; - - public ProviderAnalyticsService(ProviderDbContext context) - { - _context = context; - } - - public async Task> GetProviderCountByAreaAsync() - { - return await _context.Providers - .GroupBy(p => p.Area) - .Select(g => new { Area = g.Key, Count = g.Count() }) - .ToDictionaryAsync(x => x.Area, x => x.Count); - } - - public async Task> GetRecentlyModifiedProvidersAsync(int days = 7) - { - var cutoffDate = DateTime.UtcNow.AddDays(-days); - return await _context.Providers - .Where(p => p.UpdatedAt >= cutoffDate) - .OrderByDescending(p => p.UpdatedAt) - .ToListAsync(); - } - - public async Task> GetAvailableAreasAsync() - { - return await _context.Providers - .Select(p => p.Area) - .Distinct() - .OrderBy(area => area) - .ToListAsync(); - } -} -``` - -### Batch Operations - -```csharp -public class ProviderBatchService -{ - private readonly IProviderRepository _repository; - - public ProviderBatchService(IProviderRepository repository) - { - _repository = repository; - } - - public async Task ImportProvidersAsync(IEnumerable imports) - { - var providers = imports.Select(import => new Provider - { - Area = import.Area, - Name = import.Name, - DisplayName = import.DisplayName, - ModuleType = import.ModuleType, - IsActive = import.IsActive, - Options = import.Options - }); - - await _repository.AddMany(providers); - } - - public async Task BulkUpdateProviderStatusAsync(string area, bool isActive) - { - var providers = await _repository.GetByArea(area); - - foreach (var provider in providers) - { - provider.IsActive = isActive; - await _repository.Update(provider); - } - } -} +dotnet add package FluentCMS.Providers.Repositories.EntityFramework ``` -## Advanced Configuration +## Usage -### Custom DbContext Configuration +To set up the repository provider, register the Entity Framework provider in your dependency injection container: ```csharp -public class CustomProviderDbContext : ProviderDbContext -{ - public CustomProviderDbContext(DbContextOptions options) - : base(options) - { - } - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - base.OnModelCreating(modelBuilder); - - // Custom configurations - modelBuilder.Entity(entity => - { - // Custom table name - entity.ToTable("CmsProviders"); - - // Additional indexes - entity.HasIndex(p => p.CreatedAt) - .HasDatabaseName("IX_Provider_CreatedAt"); - - // Custom check constraints for your database - if (Database.IsNpgsql()) // PostgreSQL - { - entity.ToTable(t => t.HasCheckConstraint( - "CK_Provider_SingleActivePerArea_PG", - "IsActive = false OR NOT EXISTS (SELECT 1 FROM \"CmsProviders\" p2 WHERE p2.\"Area\" = \"Area\" AND p2.\"IsActive\" = true AND p2.\"Id\" != \"Id\")")); - } - }); - } -} -``` - -### Multi-Tenant Support - -```csharp -public class TenantProviderDbContext : ProviderDbContext -{ - private readonly ITenantProvider _tenantProvider; - - public TenantProviderDbContext( - DbContextOptions options, - ITenantProvider tenantProvider) - : base(options) - { - _tenantProvider = tenantProvider; - } - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - base.OnModelCreating(modelBuilder); - - modelBuilder.Entity(entity => - { - // Add tenant ID column - entity.Property("TenantId") - .HasMaxLength(50) - .IsRequired(); - - // Add tenant to unique constraint - entity.HasIndex(p => new { p.Area, p.Name, EF.Property(p, "TenantId") }) - .IsUnique() - .HasDatabaseName("UX_Provider_Area_Name_Tenant"); - - // Global query filter for tenant isolation - entity.HasQueryFilter(p => EF.Property(p, "TenantId") == _tenantProvider.TenantId); - }); - } - - public override async Task SaveChangesAsync(CancellationToken cancellationToken = default) - { - // Automatically set tenant ID - var entries = ChangeTracker.Entries() - .Where(e => e.State == EntityState.Added); - - foreach (var entry in entries) - { - entry.Property("TenantId").CurrentValue = _tenantProvider.TenantId; - } - - return await base.SaveChangesAsync(cancellationToken); - } -} -``` - -### Performance Optimization - -```csharp -// Read-only repository for performance-critical scenarios -public class ReadOnlyProviderRepository -{ - private readonly ProviderDbContext _context; - - public ReadOnlyProviderRepository(ProviderDbContext context) - { - _context = context; - } - - public async Task GetActiveProviderAsync(string area) - { - return await _context.Providers - .AsNoTracking() - .Where(p => p.Area == area && p.IsActive) - .FirstOrDefaultAsync(); - } - - public async Task> GetProvidersByAreasAsync(IEnumerable areas) - { - return await _context.Providers - .AsNoTracking() - .Where(p => areas.Contains(p.Area)) - .OrderBy(p => p.Area) - .ThenBy(p => p.Name) - .ToListAsync(); - } -} -``` - -## Error Handling - -### Common Database Errors - -```csharp -public class ProviderRepositoryExtensions -{ - public static async Task ExecuteWithRetryAsync( - Func> operation, - ILogger logger, - int maxRetries = 3) - { - for (int attempt = 1; attempt <= maxRetries; attempt++) - { - try - { - return await operation(); - } - catch (DbUpdateConcurrencyException ex) - { - logger.LogWarning("Concurrency conflict on attempt {Attempt}/{MaxRetries}", attempt, maxRetries); - - if (attempt == maxRetries) - throw new InvalidOperationException("Operation failed due to concurrent modifications", ex); - - await Task.Delay(TimeSpan.FromMilliseconds(100 * attempt)); - } - catch (DbUpdateException ex) when (ex.InnerException?.Message.Contains("UNIQUE") == true) - { - throw new InvalidOperationException("A provider with the same name already exists in this area", ex); - } - } - - throw new InvalidOperationException("Operation failed after maximum retries"); - } -} -``` - -## Migration Scripts - -### Initial Migration - -```csharp -// Add-Migration InitialCreate -public partial class InitialCreate : Migration -{ - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "Providers", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false), - Name = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false), - DisplayName = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false), - Area = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), - ModuleType = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false), - IsActive = table.Column(type: "bit", nullable: false, defaultValue: false), - Options = table.Column(type: "nvarchar(4000)", maxLength: 4000, nullable: true), - CreatedAt = table.Column(type: "datetime2", nullable: false, defaultValueSql: "GETUTCDATE()"), - UpdatedAt = table.Column(type: "datetime2", nullable: false, defaultValueSql: "GETUTCDATE()"), - CreatedBy = table.Column(type: "nvarchar(255)", maxLength: 255, nullable: true), - UpdatedBy = table.Column(type: "nvarchar(255)", maxLength: 255, nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Providers", x => x.Id); - table.CheckConstraint("CK_Provider_SingleActivePerArea", "IsActive = 0 OR NOT EXISTS (SELECT 1 FROM Providers p2 WHERE p2.Area = Area AND p2.IsActive = 1 AND p2.Id != Id)"); - }, - comment: "Stores provider configurations for the FluentCMS provider system"); - - migrationBuilder.CreateIndex( - name: "IX_Provider_Area", - table: "Providers", - column: "Area"); - - migrationBuilder.CreateIndex( - name: "IX_Provider_Area_IsActive", - table: "Providers", - columns: new[] { "Area", "IsActive" }, - filter: "IsActive = 1"); - - migrationBuilder.CreateIndex( - name: "IX_Provider_ModuleType", - table: "Providers", - column: "ModuleType"); - - migrationBuilder.CreateIndex( - name: "UX_Provider_Area_Name", - table: "Providers", - columns: new[] { "Area", "Name" }, - unique: true); - } +services.AddDbContext(options => + options.UseSqlServer(connectionString)); // or another EF provider - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable(name: "Providers"); - } -} +services.AddFluentCMSProviders() + .UseEntityFrameworkRepositories(); ``` -## Best Practices - -1. **Connection Management**: Use connection pooling and proper disposal -2. **Transactions**: Wrap related operations in transactions -3. **Indexing**: Create appropriate indexes for query patterns -4. **Validation**: Validate data before database operations -5. **Error Handling**: Implement proper exception handling and logging -6. **Performance**: Use `AsNoTracking()` for read-only operations -7. **Security**: Use parameterized queries (handled by EF Core) - ## Dependencies -- Microsoft.EntityFrameworkCore (>= 9.0.0) -- Microsoft.EntityFrameworkCore.SqlServer (>= 9.0.0) [or your preferred provider] -- FluentCMS.Providers.Abstractions -- FluentCMS.Providers +- Entity Framework Core -## See Also +## License -- [FluentCMS.Providers](../FluentCMS.Providers/README.md) - Core provider system -- [FluentCMS.Providers.Abstractions](../FluentCMS.Providers.Abstractions/README.md) - Provider abstractions -- [Entity Framework Core Documentation](https://docs.microsoft.com/en-us/ef/core/) +This project is licensed under the MIT License. diff --git a/src/Providers/FluentCMS.Infrastructure.Providers/README.md b/src/Providers/FluentCMS.Infrastructure.Providers/README.md index 5b8fb19..a6d2609 100644 --- a/src/Providers/FluentCMS.Infrastructure.Providers/README.md +++ b/src/Providers/FluentCMS.Infrastructure.Providers/README.md @@ -1,314 +1,55 @@ -# FluentCMS.Providers +# FluentCMS Infrastructure Providers -The core provider system for FluentCMS that enables pluggable functionality through a modular architecture. This system allows different implementations of services to be registered, discovered, and resolved at runtime. +FluentCMS Infrastructure Providers is a NuGet package that provides essential service providers for the FluentCMS Infrastructure framework. This package enables the dynamic discovery, management, and configuration of provider modules, facilitating extensible and modular hosting and logging capabilities within FluentCMS applications. -## Overview +## Features -The provider system is designed to support multiple implementations of the same functionality (e.g., different email providers, file storage providers) while ensuring only one provider per functional area is active at any time. +- **Hosting Providers**: Integrate with Microsoft.Extensions.Hosting for robust application hosting. +- **Logging Providers**: Utilize Microsoft.Extensions.Logging.Console for console-based logging. +- **Dynamic Provider Discovery**: Automatically scan and load provider modules from DLLs in the executable directory. +- **Thread-Safe Caching**: Ensure safe concurrent access to provider catalogs and modules. +- **Configuration Management**: Support for provider configuration via JSON or in-memory settings. -## Key Features +## Installation -- **Modular Architecture**: Plugin-based system supporting hot-swappable providers -- **Thread-Safe Operations**: Concurrent access with proper synchronization -- **Automatic Discovery**: Assembly scanning for provider modules -- **Configuration Support**: Both database and configuration file-based provider management -- **Dependency Injection**: Full ASP.NET Core DI integration -- **Performance Optimized**: Caching, lazy loading, and optimized reflection operations +Install the package via NuGet Package Manager: -## Core Components - -### ProviderManager -The central orchestrator that manages provider lifecycle and resolution. - -```csharp -public interface IProviderManager -{ - Task GetProviderModule(string area, string typeName, CancellationToken cancellationToken = default!); - Task GetActiveByArea(string area, CancellationToken cancellationToken = default); - Task RefreshProviders(CancellationToken cancellationToken = default); -} ``` - -### ProviderCatalogCache -Thread-safe cache for provider catalogs with immutable collections. - -```csharp -// Get active provider for an area -var catalog = providerCatalogCache.GetActiveCatalog("Email"); - -// Get specific provider -var provider = providerCatalogCache.GetCatalog("Email", "SmtpProvider"); +dotnet add package FluentCMS.Infrastructure.Providers ``` -### ProviderDiscovery -Discovers provider modules from assemblies with performance optimizations. +## Usage -```csharp -var discovery = new ProviderDiscovery(options); -var modules = discovery.GetProviderModules(); -``` +To integrate FluentCMS Infrastructure Providers into your application, configure the services in your `Program.cs` or startup code: -## Setup and Configuration +```csharp +using FluentCMS.Infrastructure.Providers; -### 1. Basic Setup +var builder = WebApplication.CreateBuilder(args); -```csharp -// In Program.cs or Startup.cs -services.AddProviders(options => +// Add provider services +builder.Services.AddProviders(options => { - options.AssemblyPrefixesToScan.Add("FluentCMS"); - options.AssemblyPrefixesToScan.Add("MyCompany.Providers"); + // Configure options as needed options.EnableLogging = true; - options.IgnoreExceptions = false; + options.AssemblyPrefixes = ["FluentCMS.Provider"]; }); -``` - -### 2. Using Configuration Files - -```csharp -services.AddProviders() - .UseConfiguration(); -``` - -**appsettings.json:** -```json -{ - "Providers": { - "Email": { - "SmtpProvider": { - "Name": "SmtpProvider", - "Active": true, - "Module": "MyCompany.Email.SmtpProviderModule", - "Options": { - "SmtpServer": "smtp.gmail.com", - "Port": 587, - "UseSsl": true - } - } - }, - "Storage": { - "LocalFileProvider": { - "Name": "LocalFileProvider", - "Active": true, - "Module": "MyCompany.Storage.LocalFileProviderModule", - "Options": { - "BasePath": "/var/storage" - } - } - } - } -} -``` - -### 3. Using Entity Framework - -```csharp -services.AddProviders() - .UseEntityFramework(); - -// DbContext registration -services.AddDbContext(options => - options.UseSqlServer(connectionString)); -``` - -## Creating Custom Providers - -### 1. Define Your Interface - -```csharp -public interface IEmailProvider : IProvider -{ - Task SendEmailAsync(string to, string subject, string body); -} -``` - -### 2. Create Provider Implementation - -```csharp -public class SmtpProvider : IEmailProvider -{ - private readonly SmtpOptions _options; - - public SmtpProvider(SmtpOptions options) - { - _options = options; - } - - public async Task SendEmailAsync(string to, string subject, string body) - { - // Implementation here - } -} -``` -### 3. Create Options Class +// Configure other services... -```csharp -public class SmtpOptions -{ - public string SmtpServer { get; set; } = string.Empty; - public int Port { get; set; } = 587; - public bool UseSsl { get; set; } = true; - public string Username { get; set; } = string.Empty; - public string Password { get; set; } = string.Empty; -} -``` - -### 4. Create Provider Module - -```csharp -public class SmtpProviderModule : ProviderModuleBase -{ - public override string Area => "Email"; - public override string DisplayName => "SMTP Email Provider"; - - public override void ConfigureServices(IServiceCollection services) - { - // Register additional services if needed - services.AddTransient(); - } -} -``` - -## Usage Examples +var app = builder.Build(); -### Resolving Providers - -```csharp -public class EmailService -{ - private readonly IEmailProvider _emailProvider; - - public EmailService(IEmailProvider emailProvider) - { - _emailProvider = emailProvider; - } - - public async Task SendWelcomeEmail(string userEmail) - { - await _emailProvider.SendEmailAsync( - userEmail, - "Welcome!", - "Thanks for joining us!"); - } -} +// Use the app... +app.Run(); ``` -### Managing Providers Programmatically - -```csharp -public class ProviderManagementService -{ - private readonly IProviderManager _providerManager; - private readonly IProviderRepository _repository; - - public ProviderManagementService( - IProviderManager providerManager, - IProviderRepository repository) - { - _providerManager = providerManager; - _repository = repository; - } - - public async Task SwitchEmailProvider(string newProviderName) - { - // Deactivate current provider - var currentProvider = await _repository.GetByArea("Email"); - foreach (var provider in currentProvider.Where(p => p.IsActive)) - { - provider.IsActive = false; - await _repository.Update(provider); - } - - // Activate new provider - var newProvider = await _repository.GetByAreaAndName("Email", newProviderName); - if (newProvider != null) - { - newProvider.IsActive = true; - await _repository.Update(newProvider); - } - - // Refresh cache - await _providerManager.RefreshProviders(); - } -} -``` - -## Performance Considerations - -### Caching -- Provider modules are cached after discovery -- Assembly reflection results are cached -- JSON deserialization results are cached - -### Thread Safety -- All operations are thread-safe -- Uses `ConcurrentDictionary` and `ImmutableList` collections -- Proper locking for initialization operations - -### Memory Management -- Assembly loading uses `AssemblyLoadContext` for better cleanup -- Disposal patterns implemented where needed -- Cache clearing methods available for memory pressure scenarios - -## Error Handling - -### Common Exceptions - -- `InvalidOperationException`: Provider configuration errors -- `ArgumentException`: Invalid parameters -- `JsonException`: Malformed provider options - -### Error Recovery - -```csharp -try -{ - var provider = serviceProvider.GetRequiredService(); - await provider.SendEmailAsync(to, subject, body); -} -catch (InvalidOperationException ex) when (ex.Message.Contains("No active provider")) -{ - // Handle missing provider scenario - _logger.LogError(ex, "No email provider configured"); - // Fallback logic here -} -``` - -## Troubleshooting - -### Provider Not Found -1. Ensure assembly prefix is included in `AssemblyPrefixesToScan` -2. Verify provider module has parameterless constructor -3. Check module implements `IProviderModule` correctly - -### Multiple Active Providers Error -1. Only one provider per area can be active -2. Check configuration for duplicate active entries -3. Verify database constraints are enforced - -### Assembly Loading Issues -1. Ensure all dependencies are available -2. Check assembly compatibility (.NET version) -3. Review `IgnoreExceptions` setting for debugging - -## Best Practices - -1. **Provider Design**: Keep providers stateless and thread-safe -2. **Options Pattern**: Use strongly-typed options classes -3. **Dependency Injection**: Register provider dependencies in `ConfigureServices` -4. **Error Handling**: Implement proper error handling and logging -5. **Testing**: Create mock implementations for unit testing -6. **Documentation**: Document provider configuration requirements +This sets up the provider management system, allowing your application to dynamically load and use provider modules for hosting and logging. ## Dependencies -- Microsoft.Extensions.DependencyInjection -- Microsoft.Extensions.Configuration -- Microsoft.Extensions.Options -- System.Text.Json -- System.Collections.Immutable +- Microsoft.Extensions.Hosting.Abstractions (v10.0.2) +- Microsoft.Extensions.Logging.Console (v10.0.2) -## API Reference +## License -See the [FluentCMS.Providers.Abstractions](../FluentCMS.Providers.Abstractions/README.md) project for detailed interface documentation. +This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. \ No newline at end of file diff --git a/src/Providers/README.md b/src/Providers/README.md index 4ddfe33..ef439b5 100644 --- a/src/Providers/README.md +++ b/src/Providers/README.md @@ -1,153 +1,136 @@ -# FluentCMS Core Provider System +# Providers -A comprehensive, pluggable provider system for FluentCMS that enables modular architecture through discoverable, configurable, and swappable service implementations. +> A modular provider system for FluentCMS, enabling extensible data access and feature implementation. -## Overview +## 📖 About -The FluentCMS Core Provider System is designed to support multiple implementations of the same functionality while maintaining clean separation of concerns, thread safety, and high performance. This system allows you to plug in different providers for services like email, file storage, caching, logging, and more, with only one provider active per functional area at any given time. +The Providers project is a core component of FluentCMS, providing a structured way to implement and manage pluggable provider modules. It separates abstractions from concrete implementations, utilizing Entity Framework for data persistence and supporting dynamic module discovery and management. This architecture allows for easy extension of CMS functionality through provider modules that can be discovered at runtime, configured, and injected into the application's dependency injection container. -## Architecture +## 🚀 Getting Started -``` -┌──────────────────────────────────────────────────────────────┐ -│ Application Layer │ -├──────────────────────────────────────────────────────────────┤ -│ IEmailProvider │ IStorageProvider │ ICacheProvider │ ... │ -├──────────────────────────────────────────────────────────────┤ -│ FluentCMS.Providers │ -│ ┌─────────────────┐ ┌─────────────────┐ ┌──────────────────┐│ -│ │ ProviderManager │ │ Provider │ │ Provider ││ -│ │ │ │ Discovery │ │ Resolution ││ -│ └─────────────────┘ └─────────────────┘ └──────────────────┘│ -├──────────────────────────────────────────────────────────────┤ -│ FluentCMS.Providers.Abstractions │ -│ IProvider │ IProviderModule │ ProviderModuleBase │ -├──────────────────────────────────────────────────────────────┤ -│ Repository Layer │ -│ Configuration │ Entity Framework │ -│ Repository │ Repository │ -└──────────────────────────────────────────────────────────────┘ +### Prerequisites +* .NET 10.0 or higher +* FluentCMS infrastructure dependencies + +### Installation +```bash +# Add package reference (if applicable, adjust path as needed) +dotnet add package FluentCMS.Infrastructure.Providers ``` -## Key Features +### Setup +Add provider services to your `IServiceCollection` in `Program.cs`: -- **🔌 Pluggable Architecture**: Easy provider swapping without code changes -- **🔍 Auto-Discovery**: Automatic provider module detection via assembly scanning -- **⚡ High Performance**: Optimized caching, lazy loading, and thread-safe operations -- **🛡️ Thread-Safe**: Concurrent access with proper synchronization primitives -- **📊 Configuration Flexible**: Support for both database and configuration file-based management -- **🎯 Dependency Injection**: Full ASP.NET Core DI container integration -- **📈 Performance Monitoring**: Built-in caching and performance optimizations -- **🔒 Data Integrity**: Database constraints ensuring single active provider per area +```csharp +builder.Services.AddProviders(); +``` -## Projects +### Configuration +Configure provider discovery options via `appsettings.json` or directly in code: -| Project | Description | Documentation | -|---------|-------------|---------------| -| **FluentCMS.Providers.Abstractions** | Core interfaces and base classes for provider implementations | [📖 View Documentation](FluentCMS.Providers.Abstractions/README.md) | -| **FluentCMS.Providers** | Main provider system implementation with discovery, caching, and management | [📖 View Documentation](FluentCMS.Providers/README.md) | -| **FluentCMS.Providers.Repositories.EntityFramework** | Entity Framework repository implementation for database-backed provider storage | [📖 View Documentation](FluentCMS.Providers.Repositories.EntityFramework/README.md) | +```json +{ + "Providers": { + "EnableLogging": true, + "AssemblyPrefixes": ["FluentCMS"], + "IgnoreExceptions": false + } +} +``` -## Quick Start +## 🏗️ Architecture Overview -### Installation +The Providers system is organized into several key components: -```bash -# Core provider system -dotnet add package FluentCMS.Providers +### Abstractions Layer +Defines interfaces and base classes for provider modules: +- `IProviderModule`: Generic interface for typed provider modules +- `ProviderModuleBase`: Base class implementation +- `IProvider`: Marker interface for concrete providers -# For creating custom providers -dotnet add package FluentCMS.Providers.Abstractions +### Core Implementation +Handles module discovery, caching, and management: +- **ProviderDiscovery**: Scans assemblies for provider modules +- **ProviderManager**: Manages active providers and module retrieval +- **ProviderCatalogCache**: Thread-safe caching of provider catalogs +- **ProviderModuleCatalogCache**: Caches discovered modules -# For database storage -dotnet add package FluentCMS.Providers.Repositories.EntityFramework -``` +### Data Layer +Entity Framework-based persistence: +- **ProviderRepository**: Repository pattern implementation for CRUD operations +- **ProviderDbContext**: EF Core context for provider entities +- **ProviderSchemaValidator**: Ensures database schema integrity +- **ProviderDataSeeder**: Seeds initial provider data -### Basic Setup +## ✨ Key Features -```csharp -// Program.cs -builder.Services.AddProviders(options => -{ - options.AssemblyPrefixesToScan.Add("FluentCMS"); - options.AssemblyPrefixesToScan.Add("MyCompany"); -}); +- **Dynamic Module Discovery**: Automatically detects and loads provider modules from DLLs at runtime +- **Thread-Safe Operations**: Concurrent dictionary-based caching for high-performance access +- **Dependency Injection Integration**: Seamlessly integrates with Microsoft.Extensions.DependencyInjection +- **Configurable Areas**: Organizes providers by functional areas (e.g., admin, user) +- **Active Provider Management**: Supports single active provider per area to avoid conflicts +- **Entity Framework Support**: Built-in repository pattern with EF Core for data persistence +- **Validation and Seeding**: Schema validation and automated data seeding capabilities -// Configuration-based storage -builder.Services.AddProviders().UseConfiguration(); +## 📋 Usage -// OR database storage -builder.Services.AddProviders().UseEntityFramework(); -``` +### Creating a Provider Module -### Usage +Implement `IProviderModule` for your custom provider: ```csharp -public class EmailService +public class MyProvider : IProvider { - private readonly IEmailProvider _emailProvider; - - public EmailService(IEmailProvider emailProvider) - { - _emailProvider = emailProvider; - } - - public async Task SendWelcomeEmail(string email) + // Implementation +} + +public class MyProviderOptions +{ + // Configuration options +} + +public class MyProviderModule : ProviderModuleBase +{ + public override void Configure(IServiceCollection services, string? name) { - await _emailProvider.SendEmailAsync(email, "Welcome!", "Thank you for joining!"); + services.AddSingleton(); } } ``` -## Documentation - -For detailed documentation, examples, and advanced usage scenarios, please refer to the individual project documentation: - -### 📖 **Core Documentation** -- **[FluentCMS.Providers](FluentCMS.Providers/README.md)** - Complete setup guide, configuration options, usage examples, and performance optimization -- **[FluentCMS.Providers.Abstractions](FluentCMS.Providers.Abstractions/README.md)** - Creating custom providers, interface design patterns, and best practices -- **[FluentCMS.Providers.Repositories.EntityFramework](FluentCMS.Providers.Repositories.EntityFramework/README.md)** - Database setup, migrations, advanced queries, and multi-tenant support - -### 🚀 **Key Topics Covered** -- **Getting Started**: Installation, basic setup, and first provider -- **Provider Development**: Creating custom providers with step-by-step guides -- **Configuration**: Multiple storage options (configuration files, database) -- **Performance**: Caching strategies, optimization tips, and benchmarks -- **Advanced Scenarios**: Provider switching, health monitoring, multi-environment setup -- **Database Integration**: Schema design, migrations, and advanced queries -- **Troubleshooting**: Common issues, debugging tips, and solutions - -## Performance & Reliability - -This system has been optimized for production use with: - -- **Thread-safe operations** with proper synchronization -- **Memory-efficient** assembly loading and caching -- **Database integrity** constraints and transaction management -- **High-performance** provider resolution (O(1) cached lookups) -- **Comprehensive error handling** with meaningful diagnostics - -For detailed performance characteristics and optimization guides, see the [FluentCMS.Providers documentation](FluentCMS.Providers/README.md#performance-considerations). +### Registering and Using Providers -## Contributing +Configure providers in your startup: -1. Fork the repository -2. Create a feature branch -3. Add comprehensive tests -4. Update relevant documentation -5. Submit a pull request +```csharp +builder.AddProviders() + .AddEntityFrameworkProviders(); +``` -## License +Access providers through `IProviderManager`: -This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. +```csharp +public class MyService +{ + private readonly IProviderManager _providerManager; -## Support + public MyService(IProviderManager providerManager) + { + _providerManager = providerManager; + } -- 📚 **Documentation**: Individual project README files contain comprehensive guides -- 🐛 **Issues**: Report bugs or request features on GitHub -- 💬 **Discussions**: Join the community discussions -- 📧 **Contact**: Reach out to the maintainers + public async Task GetActiveProvider(string area) + { + var activeByArea = await _providerManager.GetActiveByArea(area); + // Use the active provider + } +} +``` ---- +## 📦 Dependencies -*Built with ❤️ for the FluentCMS ecosystem* +* Microsoft.Extensions.DependencyInjection.Abstractions (10.0.2) +* Microsoft.Extensions.Hosting.Abstractions (10.0.2) +* Microsoft.Extensions.Logging.Console (10.0.2) +* FluentCMS Core Repositories +* Entity Framework Core (via Repositories) \ No newline at end of file diff --git a/src/README.md b/src/README.md new file mode 100644 index 0000000..18816f2 --- /dev/null +++ b/src/README.md @@ -0,0 +1,43 @@ +# FluentCMS.Infrastructure + +> Modular infrastructure components for the FluentCMS content management system. + +## 📖 About + +FluentCMS.Infrastructure is the core infrastructure layer of the FluentCMS system, providing essential services such as event-driven communication, data persistence with Entity Framework, database-backed configuration, centralized logging, and a pluggable architecture. It enables decoupled, scalable, and maintainable development by abstracting common concerns like data access, event handling, and plugin management, allowing the application layer to focus on business logic. + +## 🚀 Getting Started + +### Prerequisites + +* .NET 10.0 or higher + +### Installation + +```bash +# Add the necessary NuGet packages to your project +dotnet add package FluentCMS.Infrastructure.EventBus +dotnet add package FluentCMS.Infrastructure.Providers +dotnet add package FluentCMS.Infrastructure.Repositories +dotnet add package FluentCMS.Infrastructure.Configuration +dotnet add package FluentCMS.Infrastructure.Logging +dotnet add package FluentCMS.Infrastructure.Plugins +``` + +Then, configure the services in your startup class: + +```csharp +builder.Services.AddEventBus() + .AddProviders() + .AddEntityFrameworkRepositories(options => + { + // Configure your database provider (e.g., SQL Server or SQLite) + options.UseSqlServer(connectionString); + }) + .AddDatabaseConfiguration() + .AddLogging(options => + { + // Configure logging + }) + .AddPlugins(); +``` \ No newline at end of file diff --git a/src/Repositories/FluentCMS.Infrastructure.Repositories.EntityFramework.SqlServer/README.md b/src/Repositories/FluentCMS.Infrastructure.Repositories.EntityFramework.SqlServer/README.md new file mode 100644 index 0000000..3600d9d --- /dev/null +++ b/src/Repositories/FluentCMS.Infrastructure.Repositories.EntityFramework.SqlServer/README.md @@ -0,0 +1,32 @@ +# FluentCMS Infrastructure Repositories Entity Framework SQL Server + +This package implements SQL Server-specific Entity Framework repositories for FluentCMS Infrastructure. + +## Key Features + +- SQL Server data access + +## Installation + +` ` `bash + +dotnet add package FluentCMS.Infrastructure.Repositories.EntityFramework.SqlServer + +` ` ` + +## Basic Usage Example + +` ` `csharp + +services.AddFluentCmsDbContext(options => options.UseSqlServer(connectionString)); + +` ` ` + +## Dependencies + +SQL Server EF provider + +## License + +MIT License + diff --git a/src/Repositories/FluentCMS.Infrastructure.Repositories.EntityFramework.Sqlite/README.md b/src/Repositories/FluentCMS.Infrastructure.Repositories.EntityFramework.Sqlite/README.md new file mode 100644 index 0000000..19a8ce5 --- /dev/null +++ b/src/Repositories/FluentCMS.Infrastructure.Repositories.EntityFramework.Sqlite/README.md @@ -0,0 +1,42 @@ +# FluentCMS.Infrastructure.Repositories.EntityFramework.Sqlite + +This package provides SQLite-specific Entity Framework repositories for the FluentCMS Infrastructure. It enables seamless integration of SQLite databases into FluentCMS applications, offering efficient data access and management capabilities. + +## Key Features + +- **SQLite Data Access**: Simplified configuration for SQLite database operations using Entity Framework Core. +- **Fluent API**: Easy-to-use extension methods for configuring SQLite database connections. +- **Integration**: Built on top of FluentCMS Infrastructure repositories, promoting consistency across the framework. + +## Installation + +Install the package via NuGet Package Manager: + +```bash +dotnet add package FluentCMS.Infrastructure.Repositories.EntityFramework.Sqlite +``` + +## Usage + +To configure your FluentCMS application to use SQLite, use the `UseSqlite` extension method on the `DatabaseConfigurationBuilder`: + +```csharp +using FluentCMS.Infrastructure.Repositories.EntityFramework.Sqlite; + +// Assuming you have a DatabaseConfigurationBuilder instance +var builder = new DatabaseConfigurationBuilder(); + +builder.UseSqlite("Data Source=mydatabase.db"); +``` + +This sets up the Entity Framework context to use SQLite with the specified connection string. + +## Dependencies + +- [.NET 10.0](https://dotnet.microsoft.com/download/dotnet/10.0) +- [Microsoft.EntityFrameworkCore.Sqlite](https://www.nuget.org/packages/Microsoft.EntityFrameworkCore.Sqlite) (>= 10.0.2) +- [FluentCMS.Infrastructure.Repositories.EntityFramework](..\\FluentCMS.Infrastructure.Repositories.EntityFramework) + +## License + +This project is licensed under the MIT License. See [LICENSE](LICENSE) for more details. \ No newline at end of file diff --git a/src/Repositories/FluentCMS.Infrastructure.Repositories.EntityFramework/README.md b/src/Repositories/FluentCMS.Infrastructure.Repositories.EntityFramework/README.md new file mode 100644 index 0000000..145209e --- /dev/null +++ b/src/Repositories/FluentCMS.Infrastructure.Repositories.EntityFramework/README.md @@ -0,0 +1,80 @@ +# FluentCMS.Infrastructure.Repositories.EntityFramework + +This package provides Entity Framework implementations of repositories for the FluentCMS Infrastructure, enabling seamless integration of EF-based data access across the FluentCMS ecosystem. + +## Features + +- **EF-Based CRUD Operations**: Comprehensive Create, Read, Update, and Delete operations using Entity Framework. +- **Query Building**: Flexible query specifications with LINQ support for filtering, ordering, and pagination. +- **Entity Tracking**: Automatic management of entity state changes during database operations. +- **Data Seeding**: Base classes and services for initializing database data. +- **Schema Validation**: Tools for validating and creating database schemas. +- **Interceptors**: Custom EF interceptors for handling domain events and auditable entities. +- **Exception Handling**: Specialized exceptions, including `EntityNotFoundException`, for robust error management. + +## Installation + +Install the package via NuGet: + +```bash +dotnet add package FluentCMS.Infrastructure.Repositories.EntityFramework +``` + +## Usage + +### Basic Repository Usage + +```csharp +using FluentCMS.Infrastructure.Repositories.EntityFramework; + +// Assuming you have a DbContext and an entity +public class MyEntityRepository : Repository +{ + public MyEntityRepository(MyDbContext context) : base(context) { } +} + +// Using the repository +var repository = new MyEntityRepository(dbContext); + +// Create +await repository.AddAsync(new MyEntity { /* properties */ }); + +// Read +var entity = await repository.GetByIdAsync(id); + +// Update +entity.Property = "new value"; +await repository.UpdateAsync(entity); + +// Delete +await repository.DeleteAsync(entity); + +// Query with specification +var spec = new QuerySpecification() + .Where(e => e.IsActive) + .OrderBy(e => e.Name) + .Take(10); + +var results = await repository.GetAsync(spec); +``` + +### Configuration Setup + +Configure the repository services in your `Program.cs` or `Startup.cs`: + +```csharp +builder.Services.AddFluentCmsEntityFramework(options => +{ + options.AddDatabase("ConnectionString", DatabaseProvider.SqlServer); +}); +``` + +## Dependencies + +- Entity Framework Core 10.0.2 +- FluentCMS.Common +- FluentCMS.Repositories + +## License + +This project is licensed under the MIT License. \ No newline at end of file diff --git a/src/Repositories/FluentCMS.Infrastructure.Repositories/README.md b/src/Repositories/FluentCMS.Infrastructure.Repositories/README.md new file mode 100644 index 0000000..a90b194 --- /dev/null +++ b/src/Repositories/FluentCMS.Infrastructure.Repositories/README.md @@ -0,0 +1,70 @@ +# FluentCMS.Infrastructure.Repositories + +A NuGet package providing data access repositories for FluentCMS Infrastructure. + +## Description + +FluentCMS.Infrastructure.Repositories is a part of the FluentCMS ecosystem, offering repository abstractions to facilitate data access operations in the infrastructure layer. It supports CRUD operations, query specifications, pagination, database initialization conditions, schema validation, and domain events for entity operations. + +## Key Features + +- **Repository Abstractions**: Interfaces and implementations for standard data access operations via `IRepository`. +- **Query Specifications**: Fluent API for building complex queries with filtering, ordering, and pagination. +- **Pagination Support**: `PagedResult` for handling paginated data results. +- **Database Initialization**: Conditions and options for seeding and validating database schemas. +- **Domain Events**: Events for tracking entity creation, updates, and deletions. + +## Installation + +Install the package via NuGet: + +```bash +dotnet add package FluentCMS.Infrastructure.Repositories +``` + +## Usage + +Here's a basic example of using the repository interface: + +```csharp +using FluentCMS.Infrastructure.Repositories; +using FluentCMS.Infrastructure.Repositories.Abstractions; + +// Assume you have a service or class with dependency injection +public class MyService +{ + private readonly IRepository _repository; + + public MyService(IRepository repository) + { + _repository = repository; + } + + public async Task> GetAllEntitiesAsync() + { + return await _repository.GetAllAsync(); + } +} +``` + +For more advanced queries using specifications: + +```csharp +using FluentCMS.Infrastructure.Repositories.Abstractions; + +// Define a query specification +var spec = new QuerySpecification() + .Where(e => e.IsActive) + .OrderByDescending(e => e.CreatedAt) + .Paginate(page: 1, pageSize: 10); + +var result = await _repository.ListAsync(spec); +``` + +## Dependencies + +- [Microsoft.Extensions.Hosting.Abstractions](https://www.nuget.org/packages/Microsoft.Extensions.Hosting.Abstractions/) (10.0.2) + +## License + +This project is licensed under the MIT License - see the [LICENSE](../LICENSE) file for details. \ No newline at end of file