mirror of
https://github.com/ditkrg/DIT.Workflower.git
synced 2026-01-22 22:06:42 +00:00
Merge branch 'main' into dev
This commit is contained in:
commit
599ffc3dc9
@ -3,7 +3,7 @@
|
|||||||
"isRoot": true,
|
"isRoot": true,
|
||||||
"tools": {
|
"tools": {
|
||||||
"dotnet-sonarscanner": {
|
"dotnet-sonarscanner": {
|
||||||
"version": "5.6.0",
|
"version": "5.7.2",
|
||||||
"commands": [
|
"commands": [
|
||||||
"dotnet-sonarscanner"
|
"dotnet-sonarscanner"
|
||||||
]
|
]
|
||||||
|
|||||||
2
.github/workflows/deploy-nuget.yaml
vendored
2
.github/workflows/deploy-nuget.yaml
vendored
@ -38,5 +38,5 @@ jobs:
|
|||||||
run: |-
|
run: |-
|
||||||
dotnet nuget push "packages/*.nupkg" \
|
dotnet nuget push "packages/*.nupkg" \
|
||||||
--skip-duplicate \
|
--skip-duplicate \
|
||||||
--api-key ${{ secrets.NUGET__API_KEY }} \
|
--api-key ${{ secrets.NUGET_API_KEY }} \
|
||||||
--source https://api.nuget.org/v3/index.json
|
--source https://api.nuget.org/v3/index.json
|
||||||
|
|||||||
23
.github/workflows/sonarqube.yaml
vendored
Normal file
23
.github/workflows/sonarqube.yaml
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
name: Run SonarQube Analysis
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
paths-ignore:
|
||||||
|
- "**.md"
|
||||||
|
- ".vscode/**"
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: sonarqube-analysis
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
uses: ./.github/workflows/tests-base.yaml
|
||||||
|
with:
|
||||||
|
sonarqube: true
|
||||||
|
sonarqube_host: ${{ vars.SONARQUBE_HOST }}
|
||||||
|
secrets:
|
||||||
|
SONARQUBE_TOKEN: ${{ secrets.SONARQUBE_TOKEN }}
|
||||||
15
.github/workflows/tests-base.yaml
vendored
15
.github/workflows/tests-base.yaml
vendored
@ -2,6 +2,9 @@ name: Run Tests
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
branches-ignore:
|
||||||
|
- main
|
||||||
|
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- "**.md"
|
- "**.md"
|
||||||
|
|
||||||
@ -15,9 +18,11 @@ on:
|
|||||||
required: false
|
required: false
|
||||||
default: false
|
default: false
|
||||||
|
|
||||||
secrets:
|
sonarqube_host:
|
||||||
SONARQUBE_HOST:
|
type: string
|
||||||
required: false
|
required: false
|
||||||
|
|
||||||
|
secrets:
|
||||||
SONARQUBE_TOKEN:
|
SONARQUBE_TOKEN:
|
||||||
required: false
|
required: false
|
||||||
|
|
||||||
@ -28,9 +33,6 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
env:
|
env:
|
||||||
PROJECT_KEY: ditkrg_DIT.Workflower_AYF14rjSb80e2b0bns3t
|
|
||||||
SONARQUBE_HOST: ${{ secrets.SONARQUBE_HOST }}
|
|
||||||
SONARQUBE_TOKEN: ${{ secrets.SONARQUBE_TOKEN }}
|
|
||||||
ASPNETCORE_ENVIRONMENT: Testing
|
ASPNETCORE_ENVIRONMENT: Testing
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
@ -42,7 +44,6 @@ jobs:
|
|||||||
if: ${{ !inputs.sonarqube }}
|
if: ${{ !inputs.sonarqube }}
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
if: ${{ !inputs.sonarqube }}
|
|
||||||
run: dotnet test
|
run: dotnet test
|
||||||
|
|
||||||
###############################
|
###############################
|
||||||
@ -69,7 +70,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
dotnet tool run dotnet-sonarscanner begin -k:"$PROJECT_KEY" \
|
dotnet tool run dotnet-sonarscanner begin -k:"$PROJECT_KEY" \
|
||||||
-d:sonar.login="$SONARQUBE_TOKEN" \
|
-d:sonar.login="$SONARQUBE_TOKEN" \
|
||||||
-d:sonar.host.url="$SONARQUBE_HOST" \
|
-d:sonar.host.url="${{ inputs.sonarqube_host }}" \
|
||||||
-d:sonar.cs.vscoveragexml.reportsPaths=coverage.xml
|
-d:sonar.cs.vscoveragexml.reportsPaths=coverage.xml
|
||||||
|
|
||||||
dotnet build --no-incremental
|
dotnet build --no-incremental
|
||||||
|
|||||||
3
src/DIT.Workflower.DependencyInjection/Common.cs
Normal file
3
src/DIT.Workflower.DependencyInjection/Common.cs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
namespace DIT.Workflower.DependencyInjection;
|
||||||
|
|
||||||
|
public record DIContextWrapper<TContext>(TContext Context, IServiceProvider ServiceProvider);
|
||||||
@ -5,7 +5,7 @@ namespace DIT.Workflower.DependencyInjection.Extensions;
|
|||||||
public static class IServiceCollectionExtensions
|
public static class IServiceCollectionExtensions
|
||||||
{
|
{
|
||||||
|
|
||||||
public static ITransitionStart<TState, TCommand, TContext> AddWorkflowDefinition<TState, TCommand, TContext>(this IServiceCollection services, in int version = 1)
|
public static ITransitionStart<TState, TCommand, DIContextWrapper<TContext>> AddWorkflowDefinition<TState, TCommand, TContext>(this IServiceCollection services, in int version = 1)
|
||||||
where TState : struct
|
where TState : struct
|
||||||
where TCommand : struct
|
where TCommand : struct
|
||||||
{
|
{
|
||||||
@ -13,25 +13,25 @@ public static class IServiceCollectionExtensions
|
|||||||
return AddWorkflowDefinition<TState, TCommand, TContext>(services, id, version);
|
return AddWorkflowDefinition<TState, TCommand, TContext>(services, id, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ITransitionStart<TState, TCommand, TContext> AddWorkflowDefinition<TState, TCommand, TContext>(this IServiceCollection services, in string id)
|
public static ITransitionStart<TState, TCommand, DIContextWrapper<TContext>> AddWorkflowDefinition<TState, TCommand, TContext>(this IServiceCollection services, in string id)
|
||||||
where TState : struct
|
where TState : struct
|
||||||
where TCommand : struct
|
where TCommand : struct
|
||||||
{
|
{
|
||||||
return AddWorkflowDefinition<TState, TCommand, TContext>(services, id, version: 1);
|
return AddWorkflowDefinition<TState, TCommand, TContext>(services, id, version: 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ITransitionStart<TState, TCommand, TContext> AddWorkflowDefinition<TState, TCommand, TContext>(this IServiceCollection services, string id, int version)
|
public static ITransitionStart<TState, TCommand, DIContextWrapper<TContext>> AddWorkflowDefinition<TState, TCommand, TContext>(this IServiceCollection services, string id, int version)
|
||||||
where TState : struct
|
where TState : struct
|
||||||
where TCommand : struct
|
where TCommand : struct
|
||||||
{
|
{
|
||||||
var builder = WorkflowDefinitionBuilder<TState, TCommand, TContext>.Create();
|
var builder = WorkflowDefinitionBuilder<TState, TCommand, DIContextWrapper<TContext>>.Create();
|
||||||
|
|
||||||
services.TryAddSingleton<IWorkflowFactory<TState, TCommand, TContext>, DefaultWorkflowFactory<TState, TCommand, TContext>>();
|
services.TryAddSingleton<IWorkflowFactory<TState, TCommand, DIContextWrapper<TContext>>, DefaultWorkflowFactory<TState, TCommand, DIContextWrapper<TContext>>>();
|
||||||
|
|
||||||
services.AddSingleton<IWorkflow<TState, TCommand, TContext>, WorkflowDefinitionWrapper<TState, TCommand, TContext>>(sp =>
|
services.AddSingleton<IWorkflow<TState, TCommand, DIContextWrapper<TContext>>, WorkflowDefinitionWrapper<TState, TCommand, DIContextWrapper<TContext>>>(sp =>
|
||||||
{
|
{
|
||||||
var definition = (WorkflowDefinitionBuilder<TState, TCommand, TContext>)builder;
|
var definition = (WorkflowDefinitionBuilder<TState, TCommand, DIContextWrapper<TContext>>)builder;
|
||||||
var wrapper = new WorkflowDefinitionWrapper<TState, TCommand, TContext>(definition, id, version);
|
var wrapper = new WorkflowDefinitionWrapper<TState, TCommand, DIContextWrapper<TContext>>(definition, id, version);
|
||||||
return wrapper;
|
return wrapper;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,35 @@
|
|||||||
|
namespace DIT.Workflower.DependencyInjection.Extensions;
|
||||||
|
|
||||||
|
public static class IServiceProviderExtensions
|
||||||
|
{
|
||||||
|
public static IWorkflowFactory<TState, TCommand, DIContextWrapper<TContext>> GetRequiredWorkflowFactory<TState, TCommand, TContext>(this IServiceProvider sp)
|
||||||
|
where TState : struct
|
||||||
|
where TCommand : struct
|
||||||
|
{
|
||||||
|
return sp.GetRequiredService<IWorkflowFactory<TState, TCommand, DIContextWrapper<TContext>>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IWorkflowFactory<TState, TCommand, DIContextWrapper<TContext>>? GetWorkflowFactory<TState, TCommand, TContext>(this IServiceProvider sp)
|
||||||
|
where TState : struct
|
||||||
|
where TCommand : struct
|
||||||
|
{
|
||||||
|
return sp.GetService<IWorkflowFactory<TState, TCommand, DIContextWrapper<TContext>>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IWorkflow<TState, TCommand, DIContextWrapper<TContext>> CreateWorkflow<TState, TCommand, TContext>(this IServiceProvider sp, int version = 1)
|
||||||
|
where TState : struct
|
||||||
|
where TCommand : struct
|
||||||
|
{
|
||||||
|
var factory = GetRequiredWorkflowFactory<TState, TCommand, TContext>(sp);
|
||||||
|
return factory.CreateWorkflow(version);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IWorkflow<TState, TCommand, DIContextWrapper<TContext>> CreateWorkflow<TState, TCommand, TContext>(this IServiceProvider sp, string id, int version = 1)
|
||||||
|
where TState : struct
|
||||||
|
where TCommand : struct
|
||||||
|
{
|
||||||
|
var factory = GetRequiredWorkflowFactory<TState, TCommand, TContext>(sp);
|
||||||
|
return factory.CreateWorkflow(id, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -18,7 +18,13 @@ public record WorkflowDefinitionWrapper<TState, TCommand, TContext> : WorkflowDe
|
|||||||
|
|
||||||
public static string GetDefaultId()
|
public static string GetDefaultId()
|
||||||
{
|
{
|
||||||
return $"{typeof(TState).Name}_{typeof(TCommand).Name}_{typeof(TContext).Name}";
|
var ctxType = typeof(TContext);
|
||||||
|
var ctxName = ctxType.Name;
|
||||||
|
|
||||||
|
if (ctxType.IsGenericType)
|
||||||
|
ctxName = string.Join("+", typeof(TContext).GetGenericArguments().Select(x => x.Name));
|
||||||
|
|
||||||
|
return $"{typeof(TState).Name}_{typeof(TCommand).Name}_{ctxName}";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,8 +40,7 @@ public class DependencyInjectionTests
|
|||||||
|
|
||||||
var sp = sc.BuildServiceProvider();
|
var sp = sc.BuildServiceProvider();
|
||||||
|
|
||||||
var workflowFactory = sp.GetRequiredService<IWorkflowFactory<PhoneState, PhoneCommand, PhoneCall>>();
|
var workflowFactory = sp.GetRequiredWorkflowFactory<PhoneState, PhoneCommand, PhoneCall>();
|
||||||
|
|
||||||
|
|
||||||
var v1 = workflowFactory.CreateWorkflow(id);
|
var v1 = workflowFactory.CreateWorkflow(id);
|
||||||
var v2 = workflowFactory.CreateWorkflow(id, version: 2);
|
var v2 = workflowFactory.CreateWorkflow(id, version: 2);
|
||||||
@ -62,6 +61,7 @@ public class DependencyInjectionTests
|
|||||||
public void IdGenerationTest()
|
public void IdGenerationTest()
|
||||||
{
|
{
|
||||||
var sc = new ServiceCollection();
|
var sc = new ServiceCollection();
|
||||||
|
const string expectedId = "PhoneState_PhoneCommand_PhoneCall";
|
||||||
|
|
||||||
sc.AddWorkflowDefinition<PhoneState, PhoneCommand, PhoneCall>(version: 1)
|
sc.AddWorkflowDefinition<PhoneState, PhoneCommand, PhoneCall>(version: 1)
|
||||||
.From(PhoneState.Idle)
|
.From(PhoneState.Idle)
|
||||||
@ -69,10 +69,12 @@ public class DependencyInjectionTests
|
|||||||
.To(PhoneState.Ringing);
|
.To(PhoneState.Ringing);
|
||||||
|
|
||||||
var sp = sc.BuildServiceProvider();
|
var sp = sc.BuildServiceProvider();
|
||||||
var workflowFactory = sp.GetRequiredService<IWorkflowFactory<PhoneState, PhoneCommand, PhoneCall>>();
|
var workflowFactory = sp.GetRequiredWorkflowFactory<PhoneState, PhoneCommand, PhoneCall>();
|
||||||
var workflow = workflowFactory.CreateWorkflow();
|
var workflow = workflowFactory.CreateWorkflow();
|
||||||
|
|
||||||
Assert.Equal("PhoneState_PhoneCommand_PhoneCall", workflow.Id);
|
Assert.Equal(expectedId, workflow.Id);
|
||||||
|
Assert.Equal(expectedId, sp.CreateWorkflow<PhoneState, PhoneCommand, PhoneCall>().Id);
|
||||||
|
Assert.Equal(expectedId, sp.CreateWorkflow<PhoneState, PhoneCommand, PhoneCall>(expectedId).Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -86,7 +88,7 @@ public class DependencyInjectionTests
|
|||||||
.To(PhoneState.Ringing);
|
.To(PhoneState.Ringing);
|
||||||
|
|
||||||
var sp = sc.BuildServiceProvider();
|
var sp = sc.BuildServiceProvider();
|
||||||
var workflowFactory = sp.GetRequiredService<IWorkflowFactory<PhoneState, PhoneCommand, PhoneCall>>();
|
var workflowFactory = sp.GetRequiredWorkflowFactory<PhoneState, PhoneCommand, PhoneCall>();
|
||||||
Assert.Throws<KeyNotFoundException>(() => workflowFactory.CreateWorkflow("unknown"));
|
Assert.Throws<KeyNotFoundException>(() => workflowFactory.CreateWorkflow("unknown"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user