Merge branch 'main' into dev

This commit is contained in:
Shkar T. Noori 2024-04-28 11:32:13 +03:00
commit 599ffc3dc9
No known key found for this signature in database
GPG Key ID: C5E1A00F3BB78732
9 changed files with 94 additions and 24 deletions

View File

@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"dotnet-sonarscanner": {
"version": "5.6.0",
"version": "5.7.2",
"commands": [
"dotnet-sonarscanner"
]
@ -15,4 +15,4 @@
]
}
}
}
}

View File

@ -38,5 +38,5 @@ jobs:
run: |-
dotnet nuget push "packages/*.nupkg" \
--skip-duplicate \
--api-key ${{ secrets.NUGET__API_KEY }} \
--api-key ${{ secrets.NUGET_API_KEY }} \
--source https://api.nuget.org/v3/index.json

23
.github/workflows/sonarqube.yaml vendored Normal file
View 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 }}

View File

@ -2,6 +2,9 @@ name: Run Tests
on:
push:
branches-ignore:
- main
paths-ignore:
- "**.md"
@ -15,9 +18,11 @@ on:
required: false
default: false
secrets:
SONARQUBE_HOST:
sonarqube_host:
type: string
required: false
secrets:
SONARQUBE_TOKEN:
required: false
@ -28,9 +33,6 @@ jobs:
runs-on: ubuntu-latest
env:
PROJECT_KEY: ditkrg_DIT.Workflower_AYF14rjSb80e2b0bns3t
SONARQUBE_HOST: ${{ secrets.SONARQUBE_HOST }}
SONARQUBE_TOKEN: ${{ secrets.SONARQUBE_TOKEN }}
ASPNETCORE_ENVIRONMENT: Testing
steps:
@ -42,7 +44,6 @@ jobs:
if: ${{ !inputs.sonarqube }}
- name: Run tests
if: ${{ !inputs.sonarqube }}
run: dotnet test
###############################
@ -69,7 +70,7 @@ jobs:
run: |
dotnet tool run dotnet-sonarscanner begin -k:"$PROJECT_KEY" \
-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
dotnet build --no-incremental

View File

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

View File

@ -5,7 +5,7 @@ namespace DIT.Workflower.DependencyInjection.Extensions;
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 TCommand : struct
{
@ -13,25 +13,25 @@ public static class IServiceCollectionExtensions
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 TCommand : struct
{
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 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 wrapper = new WorkflowDefinitionWrapper<TState, TCommand, TContext>(definition, id, version);
var definition = (WorkflowDefinitionBuilder<TState, TCommand, DIContextWrapper<TContext>>)builder;
var wrapper = new WorkflowDefinitionWrapper<TState, TCommand, DIContextWrapper<TContext>>(definition, id, version);
return wrapper;
});

View File

@ -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);
}
}

View File

@ -18,7 +18,13 @@ public record WorkflowDefinitionWrapper<TState, TCommand, TContext> : WorkflowDe
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}";
}
}

View File

@ -40,8 +40,7 @@ public class DependencyInjectionTests
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 v2 = workflowFactory.CreateWorkflow(id, version: 2);
@ -62,6 +61,7 @@ public class DependencyInjectionTests
public void IdGenerationTest()
{
var sc = new ServiceCollection();
const string expectedId = "PhoneState_PhoneCommand_PhoneCall";
sc.AddWorkflowDefinition<PhoneState, PhoneCommand, PhoneCall>(version: 1)
.From(PhoneState.Idle)
@ -69,10 +69,12 @@ public class DependencyInjectionTests
.To(PhoneState.Ringing);
var sp = sc.BuildServiceProvider();
var workflowFactory = sp.GetRequiredService<IWorkflowFactory<PhoneState, PhoneCommand, PhoneCall>>();
var workflowFactory = sp.GetRequiredWorkflowFactory<PhoneState, PhoneCommand, PhoneCall>();
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]
@ -86,7 +88,7 @@ public class DependencyInjectionTests
.To(PhoneState.Ringing);
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"));
}