Skip to content

Commit

Permalink
Updated the documentations
Browse files Browse the repository at this point in the history
  • Loading branch information
Farshad DASHTI authored and Farshad DASHTI committed Oct 3, 2024
1 parent d5f507a commit d87a4e6
Show file tree
Hide file tree
Showing 7 changed files with 376 additions and 1 deletion.
96 changes: 95 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,96 @@
# DfE.CoreLibs

DfE Core Libraries
==================

This repository consists of a .NET solution containing multiple class libraries, with each library published as a standalone NuGet package. The libraries follow the naming convention: `DfE.CoreLibs.{library_name}`.

Adding a New Library to the Repository
--------------------------------------

To add a new library to this repository and automatically publish it as a NuGet package, follow these steps:

1. **Create a new library** in the `src` folder in the root of the solution.
2. **Copy the two YAML workflow files** used for other libraries (e.g., from `Caching`) into your new library directory, and modify them as needed to match your new library.

### File 1: `build-test-{library_name}.yml`

For example, if your new library is called "FileService," name the file `build-test-FileService.yml`.

#### Example Content (Replace with your library name):

```yaml
name: Build DfE.CoreLibs.FileService

on:
push:
branches:
- main
paths:
- 'src/DfE.CoreLibs.FileService/**'

jobs:
build-and-test:
uses: ./.github/workflows/build-test-template.yml
with:
project_name: DfE.CoreLibs.FileService
project_path: src/DfE.CoreLibs.FileService
sonar_project_key: DFE-Digital_corelibs-fileservice
secrets:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
```
Make sure to:
* Replace `DfE.CoreLibs.FileService` with your new library name.
* Ensure the path to the new library is correct.

### File 2: `pack-{library_name}.yml`

For example, name the file `pack-FileService.yml` for your new library.

#### Example Content (Replace with your library name):

```yaml
name: Pack DfE.CoreLibs.FileService
on:
workflow_run:
workflows: ["Build DfE.CoreLibs.FileService"]
types:
- completed
jobs:
build-and-package:
uses: ./.github/workflows/nuget-package-template.yml
with:
project_name: DfE.CoreLibs.FileService
project_path: src/DfE.CoreLibs.FileService
nuget_package_name: DfE.CoreLibs.FileService
```


Workflows Explanation
---------------------

* **Build and Test Workflow** (`build-test-{library_name}.yml`): This workflow is responsible for building and testing your library.
* **Pack Workflow** (`pack-{library_name}.yml`): This workflow handles versioning and packaging of your library, but it only runs after the build and test workflow successfully completes.

Versioning and Auto-Publishing
------------------------------

* **Initial Versioning:** The first time your library is published, the version will start at `1.0.0`.
* **Automatic Increment:** With subsequent changes, the patch version will increment automatically (e.g., `1.0.1`, `1.0.2`, and so on).
* **Custom Version Bumps:** To bump the **minor** or **major** version of your library, follow these steps:
1. Make the necessary changes in your library.
2. Commit your changes with a message like the following:

(#update {Project_Name} package version to {version_number})

Example:

(#update DfE.CoreLibs.FileService package version to 1.1.0)


The packaging workflow will then automatically set the version to `1.1.0` and increment the patch part (`1.1.x`) with each further change.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PackageReadmeFile>readme.md</PackageReadmeFile>
<Title>DfE.CoreLibs.BackgroundService</Title>
<Description>This package provides a robust framework for implementing long-running background tasks in .NET applications. It simplifies the development of background services by offering reusable components that streamline task scheduling, execution, and error handling. Ideal for any project requiring background processing, it ensures reliability and scalability across different environments.</Description>
<Authors>DFE-Digital</Authors>
</PropertyGroup>

<ItemGroup>
Expand All @@ -14,4 +18,10 @@
<PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup>

<ItemGroup>
<None Update="readme.md">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
85 changes: 85 additions & 0 deletions src/DfE.CoreLibs.BackgroundService/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# DfE.CoreLibs.BackgroundService

This library provides a robust framework for implementing long-running background tasks in .NET applications. It simplifies the development of background services by offering reusable components that streamline task scheduling, execution, and error handling. Ideal for any project requiring background processing, it ensures reliability and scalability across different environments.

## Installation

To install the DfE.CoreLibs.BackgroundService Library, use the following command in your .NET project:

```sh
dotnet add package DfE.CoreLibs.BackgroundService
```

## Usage


**Usage in a Command Handler**

1. **Service Registration:** You use a background service factory to enqueue tasks. Register the factory in your `Program.cs`:

```csharp
public void ConfigureServices(IServiceCollection services)
{
services.AddBackgroundService();
}
```


2. **Implementation in the Handler:** You enqueue tasks using `IBackgroundServiceFactory` directly inside a command handler, optionally you can pass in an event to be raised when the task is completed, as shown in your code:

```csharp
public class CreateReportCommandHandler : IRequestHandler<CreateReportCommand, bool>
{
private readonly IBackgroundServiceFactory _backgroundServiceFactory;

public CreateReportCommandHandler(IBackgroundServiceFactory backgroundServiceFactory)
{
_backgroundServiceFactory = backgroundServiceFactory;
}

public Task<bool> Handle(CreateReportCommand request, CancellationToken cancellationToken)
{
var taskName = "Create_Report_Task1";

_backgroundServiceFactory.EnqueueTask(
async () => await (new CreateReportExampleTask()).RunAsync(taskName),
result => new CreateReportExampleTaskCompletedEvent(taskName, result)
);

return Task.FromResult(true);
}
}
```

3. **Events:** The background service triggers events when a task is completed. For example:

```csharp
public class CreateReportExampleTaskCompletedEvent : IBackgroundServiceEvent
{
public string TaskName { get; }
public string Message { get; }

public CreateReportExampleTaskCompletedEvent(string taskName, string message)
{
TaskName = taskName;
Message = message;
}
}
```

4. **Event Handlers:** These events are processed by event handlers. Here's an example of how you handle task completion events:

```csharp
public class SimpleTaskCompletedEventHandler : IBackgroundServiceEventHandler<CreateReportExampleTaskCompletedEvent>
{
public Task Handle(CreateReportExampleTaskCompletedEvent notification, CancellationToken cancellationToken)
{
Console.WriteLine($"Event received for Task: {notification.TaskName}, Message: {notification.Message}");
return Task.CompletedTask;
}
}
```

This setup allows you to enqueue tasks in the background, fire events when tasks complete, and handle those events using a custom event handler architecture.

* * *
10 changes: 10 additions & 0 deletions src/DfE.CoreLibs.Caching/DfE.CoreLibs.Caching.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PackageReadmeFile>readme.md</PackageReadmeFile>
<Title>DfE.CoreLibs.Caching</Title>
<Description>This caching library offers a unified, efficient caching solution for .NET projects. It provides a simple, reusable abstraction over different caching mechanisms, enabling developers to easily implement in-memory and distributed caching strategies, improving the performance and scalability of their applications.</Description>
<Authors>DFE-Digital</Authors>
</PropertyGroup>

<ItemGroup>
Expand All @@ -15,4 +19,10 @@
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="8.0.0" />
</ItemGroup>

<ItemGroup>
<None Update="readme.md">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
79 changes: 79 additions & 0 deletions src/DfE.CoreLibs.Caching/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# DfE.CoreLibs.Caching

This caching library offers a unified, efficient caching solution for .NET projects. It provides a simple, reusable abstraction over different caching mechanisms, enabling developers to easily implement in-memory and distributed caching strategies, improving the performance and scalability of their applications.

## Installation

To install the DfE.CoreLibs.Caching Library, use the following command in your .NET project:

```sh
dotnet add package DfE.CoreLibs.Caching
```

## Usage


**Usage in Handlers**

1. **Service Registration:** You use `ICacheService` in your handlers to store and retrieve data from memory to avoid unnecessary processing and database queries. Here's how you register the caching service:


```csharp
public void ConfigureServices(IServiceCollection services)
{
services.AddServiceCaching(config);
}
```


2. **Usage in Handlers:** Here's an example of how caching is used in one of your query handlers:

```csharp
public class GetPrincipalBySchoolQueryHandler(
ISchoolRepository schoolRepository,
IMapper mapper,
ICacheService cacheService)
: IRequestHandler<GetPrincipalBySchoolQuery, Principal?>
{
public async Task<Principal?> Handle(GetPrincipalBySchoolQuery request, CancellationToken cancellationToken)
{
var cacheKey = $"Principal_{CacheKeyHelper.GenerateHashedCacheKey(request.SchoolName)}";

var methodName = nameof(GetPrincipalBySchoolQueryHandler);

return await cacheService.GetOrAddAsync(cacheKey, async () =>
{
var principal= await schoolRepository
.GetPrincipalBySchoolAsync(request.SchoolName, cancellationToken);

var result = mapper.Map<Principal?>(principal);

return result;
}, methodName);
}
}
```

In this case, the query handler checks if the principals are cached by generating a unique cache key. If the data is not cached, it retrieves the data from the repository, caches it, and returns it.

### Cache Duration Based on Method Name

The caching service dynamically determines the cache duration based on the method name. This is particularly useful when you want to apply different caching durations to different query handlers.
In this example, the cache duration for `GetPrincipalBySchoolQueryHandler` is retrieved from the configuration using the method name. If no specific duration is defined for the method, it will fall back to the default cache duration.

#### Example of Cache Settings in appsettings.json

Here is the configuration for cache durations in the `appsettings.json` file:

```csharp
"CacheSettings": {
"DefaultDurationInSeconds": 60,
"Durations": {
"GetPrincipalBySchoolQueryHandler": 86400
}
}
```

This setup ensures that the `GetPrincipalBySchoolQueryHandler` cache duration is set to 24 hours (86400 seconds), while other handlers will use the default duration of 60 seconds if no specific duration is configured.

* * *
10 changes: 10 additions & 0 deletions src/DfE.CoreLibs.Testing/DfE.CoreLibs.Testing.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PackageReadmeFile>readme.md</PackageReadmeFile>
<Title>DfE.CoreLibs.Testing</Title>
<Description>Designed to enhance test automation, this library provides essential utilities and frameworks for unit and integration testing in .NET. It includes tools for mocking, assertions, and common test scenarios, helping developers write cleaner, more efficient tests that improve the overall quality and stability of their applications.</Description>
<Authors>DFE-Digital</Authors>
</PropertyGroup>

<ItemGroup>
Expand All @@ -26,4 +30,10 @@
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
</ItemGroup>

<ItemGroup>
<None Update="readme.md">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
Loading

0 comments on commit d87a4e6

Please sign in to comment.