Compare commits

...

27 Commits
0.1.2 ... main

Author SHA1 Message Date
Brusk Awat
b653f10e3e
Update README.md 2024-08-16 00:42:53 +03:00
4fd1e47787
Remove target branch from dependabot 2024-08-14 13:04:17 +03:00
6de3d47516
BREAKING: Use Scoped services for the IWorkflow in DI. 2024-08-14 12:56:39 +03:00
Ara
f6f93d4744
Merge pull request #31 from ditkrg/dev
Add generic type constraints to ListTransitionsRequest in Query.cs
2024-04-29 13:40:37 +03:00
Ara
b9c79a4781
Add generic type constraints to ListTransitionsRequest in Query.cs 2024-04-29 13:37:09 +03:00
57c0470179
Update SonarQube configuration in tests-base.yaml 2024-04-28 11:38:13 +03:00
ed95ceea93
Update dotnet-sonarscanner and dotnet-coverage versions in dotnet-tools.json 2024-04-28 11:36:30 +03:00
f76ffcbfa2
Fix conditional check for running tests in tests-base.yaml 2024-04-28 11:34:49 +03:00
b614784805
Update reviewers in dependabot.yml 2024-04-28 11:33:36 +03:00
011a2ab9aa
Merge pull request #28 from ditkrg/dev
General Improvements
2024-04-28 11:33:01 +03:00
599ffc3dc9
Merge branch 'main' into dev 2024-04-28 11:32:13 +03:00
8ec528f2e0
Update GitHub Actions workflows to use the latest versions of actions/setup-dotnet and actions/checkout 2024-04-28 11:26:40 +03:00
f99bd9b15c
Add GetAllTransitionDefinitions and GetAllowedTransitions methods to IWorkflow.cs 2024-04-28 11:17:50 +03:00
bb52ee16d5
Merge pull request #12 from ditkrg/dependabot/nuget/dev/coverlet.collector-3.2.0
Bump coverlet.collector from 3.1.2 to 3.2.0
2022-10-31 22:04:43 +03:00
dependabot[bot]
189d43cc8f
Bump coverlet.collector from 3.1.2 to 3.2.0
Bumps [coverlet.collector](https://github.com/coverlet-coverage/coverlet) from 3.1.2 to 3.2.0.
- [Release notes](https://github.com/coverlet-coverage/coverlet/releases)
- [Commits](https://github.com/coverlet-coverage/coverlet/commits/v3.2.0)

---
updated-dependencies:
- dependency-name: coverlet.collector
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-31 13:44:50 +00:00
28d4f4805f
Merge pull request #9 from ditkrg/dependabot/nuget/dev/Microsoft.NET.Test.Sdk-17.3.2
Bump Microsoft.NET.Test.Sdk from 17.3.0 to 17.3.2
2022-10-14 12:56:20 +03:00
dependabot[bot]
812ae4b672
Bump Microsoft.NET.Test.Sdk from 17.3.0 to 17.3.2
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.3.0 to 17.3.2.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Commits](https://github.com/microsoft/vstest/compare/v17.3.0...v17.3.2)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-12 07:03:12 +00:00
594eaffa87
Merge pull request #10 from ditkrg/dependabot/github_actions/dev/actions/setup-dotnet-3
Bump actions/setup-dotnet from 2 to 3
2022-10-12 10:02:26 +03:00
98f2c02ffe
Merge pull request #11 from ditkrg/dependabot/nuget/dev/Microsoft.Extensions.DependencyInjection-6.0.1
Bump Microsoft.Extensions.DependencyInjection from 6.0.0 to 6.0.1
2022-10-12 10:02:16 +03:00
dependabot[bot]
b3ac788b8f
Bump Microsoft.Extensions.DependencyInjection from 6.0.0 to 6.0.1
Bumps [Microsoft.Extensions.DependencyInjection](https://github.com/dotnet/runtime) from 6.0.0 to 6.0.1.
- [Release notes](https://github.com/dotnet/runtime/releases)
- [Commits](https://github.com/dotnet/runtime/compare/v6.0.0...v6.0.1)

---
updated-dependencies:
- dependency-name: Microsoft.Extensions.DependencyInjection
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-11 14:53:22 +00:00
dependabot[bot]
57f2188f7f
Bump actions/setup-dotnet from 2 to 3
Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 2 to 3.
- [Release notes](https://github.com/actions/setup-dotnet/releases)
- [Commits](https://github.com/actions/setup-dotnet/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/setup-dotnet
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-30 13:56:59 +00:00
8c3f6b5f55
Merge pull request #6 from ditkrg/dependabot/nuget/dev/xunit-2.4.2
Bump xunit from 2.4.1 to 2.4.2
2022-08-15 18:00:48 +03:00
dependabot[bot]
199f8ce1b5
Bump xunit from 2.4.1 to 2.4.2
Bumps [xunit](https://github.com/xunit/xunit) from 2.4.1 to 2.4.2.
- [Release notes](https://github.com/xunit/xunit/releases)
- [Commits](https://github.com/xunit/xunit/compare/2.4.1...2.4.2)

---
updated-dependencies:
- dependency-name: xunit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-15 12:27:35 +00:00
4379fb6bca
Merge pull request #7 from ditkrg/dependabot/nuget/dev/Microsoft.NET.Test.Sdk-17.3.0
Bump Microsoft.NET.Test.Sdk from 17.2.0 to 17.3.0
2022-08-15 15:27:13 +03:00
dependabot[bot]
a6ea2b6d8d
Bump Microsoft.NET.Test.Sdk from 17.2.0 to 17.3.0
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.2.0 to 17.3.0.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Commits](https://github.com/microsoft/vstest/compare/v17.2.0...v17.3.0)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-10 13:36:38 +00:00
36e4e94a44
Merge pull request #5 from ditkrg/dependabot/github_actions/dev/actions/setup-dotnet-2
Bump actions/setup-dotnet from 1 to 2
2022-07-23 10:23:50 +03:00
dependabot[bot]
3c45c128fa
Bump actions/setup-dotnet from 1 to 2
Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 1 to 2.
- [Release notes](https://github.com/actions/setup-dotnet/releases)
- [Commits](https://github.com/actions/setup-dotnet/compare/v1...v2)

---
updated-dependencies:
- dependency-name: actions/setup-dotnet
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-21 13:44:22 +00:00
17 changed files with 240 additions and 89 deletions

View File

@ -3,16 +3,16 @@
"isRoot": true,
"tools": {
"dotnet-sonarscanner": {
"version": "5.7.2",
"version": "6.2.0",
"commands": [
"dotnet-sonarscanner"
]
},
"dotnet-coverage": {
"version": "17.3.2",
"version": "17.11.0",
"commands": [
"dotnet-coverage"
]
}
}
}
}

View File

@ -4,7 +4,6 @@ updates:
# Maintain dependencies for GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
target-branch: dev
schedule:
interval: "daily"
reviewers:
@ -13,8 +12,7 @@ updates:
# Maintain dependencies for nuget
- package-ecosystem: "nuget"
directory: "/"
target-branch: dev
schedule:
interval: "daily"
reviewers:
- "ditkrg/digital-development-net"
- "ditkrg/dotnet"

View File

@ -1,3 +1,4 @@
---
name: Deploy To Nuget
on:
@ -19,13 +20,13 @@ jobs:
build-push:
name: Build and Publish
needs: [test]
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v1
- uses: actions/setup-dotnet@v4
with:
dotnet-version: "6.0.x"
dotnet-version: "8.0.x"
- name: Restore packages
run: dotnet restore

View File

@ -1,3 +1,4 @@
---
name: Run SonarQube Analysis
on:
@ -13,39 +14,10 @@ concurrency:
group: sonarqube-analysis
jobs:
run-tests:
name: Run SonarQube Analysis
timeout-minutes: 10
runs-on: ubuntu-latest
env:
PROJECT_KEY: ditkrg_DIT.Workflower_AYF14rjSb80e2b0bns3t
SONARQUBE_HOST: ${{ secrets.SONARQUBE_HOST }}
test:
uses: ./.github/workflows/tests-base.yaml
with:
sonarqube: true
sonarqube_host: ${{ vars.SONARQUBE_HOST }}
secrets:
SONARQUBE_TOKEN: ${{ secrets.SONARQUBE_TOKEN }}
ASPNETCORE_ENVIRONMENT: Testing
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
distribution: "zulu"
java-version: "11"
- name: Restore tools
run: dotnet tool restore
- name: Run Tests (SonarQube)
run: |
dotnet tool run dotnet-sonarscanner begin -k:"$PROJECT_KEY" \
-d:sonar.login="$SONARQUBE_TOKEN" \
-d:sonar.host.url="$SONARQUBE_HOST" \
-d:sonar.cs.vscoveragexml.reportsPaths=coverage.xml
dotnet build --no-incremental
dotnet dotnet-coverage collect "dotnet test" -f xml -o "coverage.xml"
dotnet tool run dotnet-sonarscanner end -d:sonar.login="$SONARQUBE_TOKEN"

View File

@ -12,6 +12,19 @@ on:
- "!.github/workflows/tests-base.yaml"
workflow_call:
inputs:
sonarqube:
type: boolean
required: false
default: false
sonarqube_host:
type: string
required: false
secrets:
SONARQUBE_TOKEN:
required: false
jobs:
run-tests:
@ -23,11 +36,49 @@ jobs:
ASPNETCORE_ENVIRONMENT: Testing
steps:
- uses: actions/checkout@v3
- uses: actions/setup-dotnet@v2
- uses: actions/setup-dotnet@v4
with:
dotnet-version: "6.0.x"
dotnet-version: "8.0.x"
- uses: actions/checkout@v4
if: ${{ !inputs.sonarqube }}
- name: Run tests
if: ${{ !inputs.sonarqube }}
run: dotnet test
###############################
########## SONARQUBE ##########
###############################
- name: Set up JDK
uses: actions/setup-java@v4
if: ${{ inputs.sonarqube }}
with:
distribution: "zulu"
java-version: "17"
- uses: actions/checkout@v4
if: ${{ inputs.sonarqube }}
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Restore tools
if: ${{ inputs.sonarqube }}
run: dotnet tool restore
- name: Run tests (SonarQube)
if: ${{ inputs.sonarqube }}
env:
PROJECT_KEY: ditkrg_DIT.Workflower_AYF14rjSb80e2b0bns3t
SONARQUBE_HOST: ${{ inputs.sonarqube_host }}
SONARQUBE_TOKEN: ${{ secrets.SONARQUBE_TOKEN }}
run: |
dotnet tool run dotnet-sonarscanner begin -k:"$PROJECT_KEY" \
-d:sonar.login="$SONARQUBE_TOKEN" \
-d:sonar.host.url="$SONARQUBE_HOST" \
-d:sonar.cs.vscoveragexml.reportsPaths=coverage.xml
dotnet build --no-incremental
dotnet dotnet-coverage collect "dotnet test" -f xml -o "coverage.xml"
dotnet tool run dotnet-sonarscanner end -d:sonar.login="$SONARQUBE_TOKEN"

View File

@ -8,15 +8,15 @@ Workflower is a library based on .NET Standard, To handle Finite State Machines
Install the latest nuget package into your ASP.NET Core application.
```sh
dotnet add package DIT.Workflower
```
```sh
dotnet add package DIT.Workflower
```
You can also download support for Dependency Injection:
You can also download support for Dependency Injection:
```sh
dotnet add package DIT.Workflower.DependencyInjection
```
```sh
dotnet add package DIT.Workflower.DependencyInjection
```
### Workflow Builder

View File

@ -10,6 +10,15 @@ public interface IWorkflow<TState, TCommand, TContext>
string Reference => $"{Id}.v{Version}";
/// <summary>
/// Retrieves all transition definitions for the workflow.
/// </summary>
/// <typeparam name="TState">The type of the workflow state.</typeparam>
/// <typeparam name="TCommand">The type of the workflow command.</typeparam>
/// <typeparam name="TContext">The type of the workflow context.</typeparam>
/// <returns>A list of transition definitions.</returns>
public List<TransitionDefinition<TState, TCommand, ContextWrapper<TContext>>> GetAllTransitionDefinitions();
/// <summary>
/// Gets a list of allowed transitions without any condition checks.
/// </summary>
@ -24,4 +33,13 @@ public interface IWorkflow<TState, TCommand, TContext>
/// <param name="from">The incoming state</param>
/// <returns>A list of available transitions for the current context</returns>
public List<Transition<TState, TCommand>> GetAllowedTransitions(TContext context, TState from);
/// <summary>
/// Retrieves a list of allowed transitions based on the provided request.
/// </summary>
/// <typeparam name="TState">The type of the workflow state.</typeparam>
/// <typeparam name="TCommand">The type of the workflow command.</typeparam>
/// <param name="request">The request object containing the necessary information.</param>
/// <returns>An enumerable of allowed transitions.</returns>
public IEnumerable<Transition<TState, TCommand>> GetAllowedTransitions(ListTransitionsRequest<TState, TCommand, TContext> request);
}

View File

@ -1,3 +1,3 @@
namespace DIT.Workflower.DependencyInjection;
public record DIContextWrapper<TContext>(TContext Context, IServiceProvider ServiceProvider);
public record ContextWrapper<TContext>(TContext Context, IServiceProvider ServiceProvider);

View File

@ -1,13 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>true</IsPackable>
<PackageId>DIT.Workflower.DependencyInjection</PackageId>
<Authors>DIT</Authors>
<Company>DIT</Company>
<!-- Symbols for nuget -->
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<!-- Deterministic Builds -->
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<ContinuousIntegrationBuild Condition="'$(CI)' == 'true'">true</ContinuousIntegrationBuild>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0" />
<ItemGroup >
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.1" Condition="'$(TargetFramework)' == 'net6.0'" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.1" Condition="'$(TargetFramework)' == 'net7.0'" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.1" Condition="'$(TargetFramework)' == 'net8.0'" />
</ItemGroup>
<ItemGroup>

View File

@ -2,10 +2,10 @@
namespace DIT.Workflower.DependencyInjection.Extensions;
public static class IServiceCollectionExtensions
public static class ServiceCollectionExtensions
{
public static ITransitionStart<TState, TCommand, DIContextWrapper<TContext>> AddWorkflowDefinition<TState, TCommand, TContext>(this IServiceCollection services, in int version = 1)
public static ITransitionStart<TState, TCommand, ContextWrapper<TContext>> AddWorkflowDefinition<TState, TCommand, TContext>(
this IServiceCollection services, in int version = 1)
where TState : struct
where TCommand : struct
{
@ -13,25 +13,27 @@ public static class IServiceCollectionExtensions
return AddWorkflowDefinition<TState, TCommand, TContext>(services, id, version);
}
public static ITransitionStart<TState, TCommand, DIContextWrapper<TContext>> AddWorkflowDefinition<TState, TCommand, TContext>(this IServiceCollection services, in string id)
public static ITransitionStart<TState, TCommand, ContextWrapper<TContext>> AddWorkflowDefinition<TState, TCommand, TContext>(
this IServiceCollection services, in string id)
where TState : struct
where TCommand : struct
{
return AddWorkflowDefinition<TState, TCommand, TContext>(services, id, version: 1);
}
public static ITransitionStart<TState, TCommand, DIContextWrapper<TContext>> AddWorkflowDefinition<TState, TCommand, TContext>(this IServiceCollection services, string id, int version)
public static ITransitionStart<TState, TCommand, ContextWrapper<TContext>> AddWorkflowDefinition<TState, TCommand, TContext>(
this IServiceCollection services, string id, int version)
where TState : struct
where TCommand : struct
{
var builder = WorkflowDefinitionBuilder<TState, TCommand, DIContextWrapper<TContext>>.Create();
var builder = WorkflowDefinitionBuilder<TState, TCommand, ContextWrapper<TContext>>.Create();
var definition = (WorkflowDefinitionBuilder<TState, TCommand, ContextWrapper<TContext>>)builder;
services.TryAddSingleton<IWorkflowFactory<TState, TCommand, DIContextWrapper<TContext>>, DefaultWorkflowFactory<TState, TCommand, DIContextWrapper<TContext>>>();
services.TryAddScoped<IWorkflowFactory<TState, TCommand, TContext>, DefaultWorkflowFactory<TState, TCommand, TContext>>();
services.AddSingleton<IWorkflow<TState, TCommand, DIContextWrapper<TContext>>, WorkflowDefinitionWrapper<TState, TCommand, DIContextWrapper<TContext>>>(sp =>
services.AddScoped<IWorkflow<TState, TCommand, TContext>, WorkflowDefinitionWrapper<TState, TCommand, TContext>>(sp =>
{
var definition = (WorkflowDefinitionBuilder<TState, TCommand, DIContextWrapper<TContext>>)builder;
var wrapper = new WorkflowDefinitionWrapper<TState, TCommand, DIContextWrapper<TContext>>(definition, id, version);
var wrapper = new WorkflowDefinitionWrapper<TState, TCommand, TContext>(definition, sp, id, version);
return wrapper;
});

View File

@ -1,22 +1,22 @@
namespace DIT.Workflower.DependencyInjection.Extensions;
public static class IServiceProviderExtensions
public static class ServiceProviderExtensions
{
public static IWorkflowFactory<TState, TCommand, DIContextWrapper<TContext>> GetRequiredWorkflowFactory<TState, TCommand, TContext>(this IServiceProvider sp)
public static IWorkflowFactory<TState, TCommand, TContext> GetRequiredWorkflowFactory<TState, TCommand, TContext>(this IServiceProvider sp)
where TState : struct
where TCommand : struct
{
return sp.GetRequiredService<IWorkflowFactory<TState, TCommand, DIContextWrapper<TContext>>>();
return sp.GetRequiredService<IWorkflowFactory<TState, TCommand, TContext>>();
}
public static IWorkflowFactory<TState, TCommand, DIContextWrapper<TContext>>? GetWorkflowFactory<TState, TCommand, TContext>(this IServiceProvider sp)
public static IWorkflowFactory<TState, TCommand, TContext>? GetWorkflowFactory<TState, TCommand, TContext>(this IServiceProvider sp)
where TState : struct
where TCommand : struct
{
return sp.GetService<IWorkflowFactory<TState, TCommand, DIContextWrapper<TContext>>>();
return sp.GetService<IWorkflowFactory<TState, TCommand, TContext>>();
}
public static IWorkflow<TState, TCommand, DIContextWrapper<TContext>> CreateWorkflow<TState, TCommand, TContext>(this IServiceProvider sp, int version = 1)
public static IWorkflow<TState, TCommand, TContext> CreateWorkflow<TState, TCommand, TContext>(this IServiceProvider sp, int version = 1)
where TState : struct
where TCommand : struct
{
@ -24,7 +24,7 @@ public static class IServiceProviderExtensions
return factory.CreateWorkflow(version);
}
public static IWorkflow<TState, TCommand, DIContextWrapper<TContext>> CreateWorkflow<TState, TCommand, TContext>(this IServiceProvider sp, string id, int version = 1)
public static IWorkflow<TState, TCommand, TContext> CreateWorkflow<TState, TCommand, TContext>(this IServiceProvider sp, string id, int version = 1)
where TState : struct
where TCommand : struct
{

View File

@ -1,21 +1,56 @@
namespace DIT.Workflower.DependencyInjection;
public record WorkflowDefinitionWrapper<TState, TCommand, TContext> : WorkflowDefinition<TState, TCommand, TContext>, IWorkflow<TState, TCommand, TContext>
public sealed class WorkflowDefinitionWrapper<TState, TCommand, TContext> : IWorkflow<TState, TCommand, TContext>
where TState : struct
where TCommand : struct
{
private readonly IServiceProvider _serviceProvider;
private readonly WorkflowDefinition<TState, TCommand, ContextWrapper<TContext>> _definition;
public string Id { get; }
public int Version { get; }
public WorkflowDefinitionWrapper(WorkflowDefinitionBuilder<TState, TCommand, TContext> builder, string id, int version)
: base(builder.Transitions)
public List<TransitionDefinition<TState, TCommand, ContextWrapper<TContext>>> GetAllTransitionDefinitions()
{
return _definition.GetAllTransitionDefinitions();
}
public List<Transition<TState, TCommand>> GetAllowedTransitions(TState from)
{
return _definition.GetAllowedTransitions(from);
}
public List<Transition<TState, TCommand>> GetAllowedTransitions(TContext context, TState from)
{
return _definition.GetAllowedTransitions(GetContextWrapper(context), from);
}
public IEnumerable<Transition<TState, TCommand>> GetAllowedTransitions(ListTransitionsRequest<TState, TCommand, TContext> request)
{
var wrappedRequest = new ListTransitionsRequest<TState, TCommand, ContextWrapper<TContext>>
{
From = request.From,
To = request.To,
Command = request.Command,
Context = request.Context is null ? null : GetContextWrapper(request.Context)
};
return _definition.GetAllowedTransitions(wrappedRequest);
}
public WorkflowDefinitionWrapper(WorkflowDefinitionBuilder<TState, TCommand, ContextWrapper<TContext>> builder, IServiceProvider serviceProvider, string id, int version)
{
_definition = builder.Build();
_serviceProvider = serviceProvider;
Id = id;
Version = version;
}
private ContextWrapper<TContext> GetContextWrapper(in TContext context)
=> new(context, _serviceProvider);
public static string GetDefaultId()
{
var ctxType = typeof(TContext);

View File

@ -5,6 +5,20 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
<IsPackable>true</IsPackable>
<PackageId>DIT.Workflower</PackageId>
<Authors>DIT</Authors>
<Company>DIT</Company>
<!-- Symbols for nuget -->
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<!-- Deterministic Builds -->
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<ContinuousIntegrationBuild Condition="'$(CI)' == 'true'">true</ContinuousIntegrationBuild>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,15 @@
namespace DIT.Workflower;
public sealed class ListTransitionsRequest<TState, TCommand, TContext>
where TState : struct
where TCommand : struct
{
public TState? From { get; set; }
public TState? To { get; set; }
public TCommand? Command { get; set; }
public TContext? Context { get; set; }
}

View File

@ -1,6 +1,6 @@
namespace DIT.Workflower;
public record WorkflowDefinition<TState, TCommand, TContext>
public class WorkflowDefinition<TState, TCommand, TContext>
where TState : struct
where TCommand : struct
{
@ -12,6 +12,8 @@ public record WorkflowDefinition<TState, TCommand, TContext>
_transitions = transitions;
}
public List<TransitionDefinition<TState, TCommand, TContext>> GetAllTransitionDefinitions() => _transitions;
/// <summary>
/// Lists all allowed transitions from current state for the given context.
/// </summary>
@ -33,4 +35,33 @@ public record WorkflowDefinition<TState, TCommand, TContext>
return query.Select(x => x.ToTransition()).ToList();
}
public IEnumerable<Transition<TState, TCommand>> GetAllowedTransitions(ListTransitionsRequest<TState, TCommand, TContext> request)
{
var query = _transitions.AsQueryable();
if (request.From is { } from)
{
query = query.Where(doc => doc.From.Equals(from));
}
if (request.To is { } to)
{
query = query.Where(doc => doc.To.Equals(to));
}
if (request.Command is { } command)
{
query = query.Where(doc => doc.Command.Equals(command));
}
if (request.Context is not null)
{
query = query.Where(doc => doc.Conditions == null || doc.Conditions.All(cond => cond(request.Context)));
}
return query.Select(x => x.ToTransition());
}
}

View File

@ -9,14 +9,14 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.2">
<PackageReference Include="coverlet.collector" Version="3.2.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>

View File

@ -1,5 +1,4 @@
using DIT.Workflower.DependencyInjection.Abstractions;
using DIT.Workflower.DependencyInjection.Extensions;
using DIT.Workflower.DependencyInjection.Extensions;
using Microsoft.Extensions.DependencyInjection;
namespace DIT.Workflower.Tests.DependencyInjection;
@ -49,7 +48,6 @@ public class DependencyInjectionTests
Assert.NotNull(v1);
Assert.NotNull(v2);
Assert.Single(v1!.GetAllowedTransitions(PhoneState.Idle));
Assert.Single(v2!.GetAllowedTransitions(PhoneState.Idle));