mirror of
https://github.com/ditkrg/DIT.Workflower.git
synced 2026-01-22 22:06:42 +00:00
Add helper functions to create workflows, access service provider in When clause
This commit is contained in:
parent
c0691416a8
commit
86c2f3e9c4
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