diff --git a/PipeAndFilter.sln b/PipeAndFilter.sln index ae9832c..a023aca 100644 --- a/PipeAndFilter.sln +++ b/PipeAndFilter.sln @@ -17,7 +17,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{0EE631D9-C EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PipeAndFilter", "Src\PipeAndFilter.csproj", "{27DC4458-EAEB-4C93-ACAF-25F25C404DBC}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PipeAndFilterSamples", "Samples\PipeAndFilterSamples.csproj", "{B8DB50CE-1D00-4FDC-B99C-F943AF0A8918}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PipeAndFilterSampleConsole", "Samples\SampleConsole\PipeAndFilterSampleConsole.csproj", "{9D70D715-9911-46B0-86D2-DB08AF72DE1D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PipeAndFilterSampleApi", "Samples\SampleApi\PipeAndFilterSampleApi.csproj", "{6696533B-7288-4B59-ADBC-919D875DA5F3}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -32,12 +34,18 @@ Global {27DC4458-EAEB-4C93-ACAF-25F25C404DBC}.local|Any CPU.Build.0 = local|Any CPU {27DC4458-EAEB-4C93-ACAF-25F25C404DBC}.Release|Any CPU.ActiveCfg = Release|Any CPU {27DC4458-EAEB-4C93-ACAF-25F25C404DBC}.Release|Any CPU.Build.0 = Release|Any CPU - {B8DB50CE-1D00-4FDC-B99C-F943AF0A8918}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B8DB50CE-1D00-4FDC-B99C-F943AF0A8918}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B8DB50CE-1D00-4FDC-B99C-F943AF0A8918}.local|Any CPU.ActiveCfg = Debug|Any CPU - {B8DB50CE-1D00-4FDC-B99C-F943AF0A8918}.local|Any CPU.Build.0 = Debug|Any CPU - {B8DB50CE-1D00-4FDC-B99C-F943AF0A8918}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B8DB50CE-1D00-4FDC-B99C-F943AF0A8918}.Release|Any CPU.Build.0 = Release|Any CPU + {9D70D715-9911-46B0-86D2-DB08AF72DE1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9D70D715-9911-46B0-86D2-DB08AF72DE1D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9D70D715-9911-46B0-86D2-DB08AF72DE1D}.local|Any CPU.ActiveCfg = Debug|Any CPU + {9D70D715-9911-46B0-86D2-DB08AF72DE1D}.local|Any CPU.Build.0 = Debug|Any CPU + {9D70D715-9911-46B0-86D2-DB08AF72DE1D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9D70D715-9911-46B0-86D2-DB08AF72DE1D}.Release|Any CPU.Build.0 = Release|Any CPU + {6696533B-7288-4B59-ADBC-919D875DA5F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6696533B-7288-4B59-ADBC-919D875DA5F3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6696533B-7288-4B59-ADBC-919D875DA5F3}.local|Any CPU.ActiveCfg = Debug|Any CPU + {6696533B-7288-4B59-ADBC-919D875DA5F3}.local|Any CPU.Build.0 = Debug|Any CPU + {6696533B-7288-4B59-ADBC-919D875DA5F3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6696533B-7288-4B59-ADBC-919D875DA5F3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/README.md b/README.md index 47279b4..4a69dfe 100644 --- a/README.md +++ b/README.md @@ -70,127 +70,86 @@ dotnet run --project [name of sample] ## Usage [**Top**](#table-of-contents) -The controls use **fluent interface**; an object-oriented API whose design relies extensively on method chaining. Its goal is to increase code legibility. The term was coined in 2005 by Eric Evans and Martin Fowler. -```csharp -public class MyClass -{ - public int MyProperty { get; set; } -} -``` +The **PipeAndFilter** use **fluent interface**; an object-oriented API whose design relies extensively on method chaining. Its goal is to increase code legibility. The term was coined in 2005 by Eric Evans and Martin Fowler. -```csharp -var contract = new MyClass { MyProperty = 10 }; +### Sample-Console Usage -var result = await PipeAndFilter - .Create() - .Init(contract) - .MaxDegreeProcess(4) - .CorrelationId(null) - .Logger(null) +```csharp +var result = await PipeAndFilter.New() .AddPipe(ExecPipe1) - .AddPipe(ExecPipe2) .WithCondition(CondFalse, "LastPipe") .WithCondition(CondTrue, null) .WithCondition(CondTrue, null) - .AddPipeTasks(AgregateTask) + .AddPipe(ExecPipe2) + .AddPipe(ExecPipe3) + .AddPipeTasks(AgregateTask) .WithCondition(CondTrue, null) - .AddTask(Task50) - .AddTaskCondition(Task100, CondFalse) - .AddTask(Task150) - .AddPipe(ExecPipe, "LastPipe") - .Run(); - -Console.WriteLine($"Contract value : {contract.MyProperty}"); -foreach (var item in pl.Status) -{ - Console.WriteLine($"{item.Alias ?? item.Id}:{item.Status.Value} => {item.Status.Elapsedtime}"); - foreach (var det in item.StatusDetails) - { - Console.WriteLine($"\t{det.TypeExec}:{det.GotoAlias ?? det.Alias}:{det.Condition} => :{det.Value}:{det.Elapsedtime}"); - } -} + .MaxDegreeProcess(4) + .AddTask(Task1) + .AddTaskCondition(Task2, CondFalse) + .AddTask(Task3) + .AddPipe(ExecPipe5, "LastPipe") + .BuildAndCreate() + .Init(contract) + .CorrelationId(null) + .Logger(null) + .Run(); ``` +### Sample-api/webUsage +[**Top**](#table-of-contents) + ```csharp -private static async Task Task50(EventPipe pipe, CancellationToken token) -{ - pipe.ChangeContract((contract) => - { - contract.MyProperty++; - }); - try - { - await Task.Delay(50, token); - pipe.SaveValue(50); - } - catch (TaskCanceledException) - { - //none - } -} -private static async Task Task100(EventPipe pipe, CancellationToken token) -{ - pipe.ChangeContract((contract) => - { - contract.MyProperty++; - }); - try - { - await Task.Delay(100, token); - pipe.SaveValue(100); - } - catch (TaskCanceledException) - { - //none - } -} -private static async Task Task150(EventPipe pipe, CancellationToken token) +builder.Services + .AddPipeAndFilter( + PipeAndFilter.New() + .AddPipe(ExecPipe) + .Build()); + +``` + +```csharp +private static Task ExecPipe(EventPipe pipe, CancellationToken token) { pipe.ChangeContract((contract) => { - contract.MyProperty++; + contract.TemperatureC += 10; }); - try - { - await Task.Delay(150, token); - pipe.SaveValue(150); - } - catch (TaskCanceledException) - { - //none - } -} -private static Task ExecPipe(EventPipe pipe, CancellationToken token) -{ - pipe.SaveValue("Saved"); - return Task.CompletedTask; -} -private static Task AgregateTask(EventPipe pipe, CancellationToken token) -{ return Task.CompletedTask; } -private static async Task ExecPipe100(EventPipe pipe, CancellationToken token) +``` + +```csharp +[ApiController] +[Route("[controller]")] +public class WeatherForecastController : ControllerBase { - pipe.SaveValue("Saved0"); - try + private readonly ILogger _logger; + private readonly IPipeAndFilterServiceBuild _mypipe; + + public WeatherForecastController(ILogger logger, IPipeAndFilterServiceBuild pipeAndFilter) { - await Task.Delay(100, token); + _logger = logger; + _mypipes = pipeAndFilter; } - catch (TaskCanceledException) + + [HttpGet(Name = "GetWeatherForecast")] + public async Task Get(CancellationToken cancellation) { - //none + var cid = Guid.NewGuid().ToString(); + + var pipe = await _mypipes.First(x => x.ServiceId == "opc1") + .Create() + .Logger(_logger) + .CorrelationId(cid) + .Init(new WeatherForecast { Date = DateOnly.FromDateTime(DateTime.Now), Summary = "PipeAndFilter-Opc1", TemperatureC = 0 }) + .Run(cancellation); + return pipe.Result.Value! } } -private static async ValueTask CondFalse(EventPipe pipe, CancellationToken token) -{ - return await Task.FromResult(false); -} -private static ValueTask CondTrue(EventPipe pipe, CancellationToken token) -{ - ValueTask.FromResult(true); -} ``` + ## Code of Conduct [**Top**](#table-of-contents) diff --git a/Samples/SampleApi/Controllers/WeatherForecastController.cs b/Samples/SampleApi/Controllers/WeatherForecastController.cs new file mode 100644 index 0000000..4b5af6b --- /dev/null +++ b/Samples/SampleApi/Controllers/WeatherForecastController.cs @@ -0,0 +1,42 @@ +using Microsoft.AspNetCore.Mvc; +using PipeFilterCore; + +namespace WebApplication1.Controllers +{ + [ApiController] + [Route("[controller]")] + public class WeatherForecastController : ControllerBase + { + + private readonly ILogger _logger; + private readonly IEnumerable> _mypipes; + + public WeatherForecastController(ILogger logger, IEnumerable> pipeAndFilter) + { + _logger = logger; + _mypipes = pipeAndFilter; + } + + [HttpGet(Name = "GetWeatherForecast")] + public async Task> Get(CancellationToken cancellation) + { + var cid = Guid.NewGuid().ToString(); + + var pipe1 = await _mypipes.First(x => x.ServiceId == "opc1") + .Create() + .Logger(_logger) + .CorrelationId(cid) + .Init(new WeatherForecast { Date = DateOnly.FromDateTime(DateTime.Now), Summary = "PipeAndFilter-Opc1", TemperatureC = 0 }) + .Run(); + + var pipe2 = await _mypipes.First(x => x.ServiceId == "opc2") + .Create() + .Logger(_logger) + .CorrelationId(cid) + .Init(new WeatherForecast { Date = DateOnly.FromDateTime(DateTime.Now), Summary = "PipeAndFilter-Opc2", TemperatureC = 100 }) + .Run(cancellation); + + return new WeatherForecast[] { pipe1.Value!, pipe2.Value! }; + } + } +} \ No newline at end of file diff --git a/Samples/SampleApi/PipeAndFilterSampleApi.csproj b/Samples/SampleApi/PipeAndFilterSampleApi.csproj new file mode 100644 index 0000000..bf3956c --- /dev/null +++ b/Samples/SampleApi/PipeAndFilterSampleApi.csproj @@ -0,0 +1,18 @@ + + + + net7.0 + enable + enable + + + + + + + + + + + + diff --git a/Samples/SampleApi/Program.cs b/Samples/SampleApi/Program.cs new file mode 100644 index 0000000..0a87f15 --- /dev/null +++ b/Samples/SampleApi/Program.cs @@ -0,0 +1,59 @@ + +using System; +using PipeFilterCore; + +namespace WebApplication1 +{ + public class Program + { + public static void Main(string[] args) + { + var builder = WebApplication.CreateBuilder(args); + + // Add services to the container. + + builder.Services.AddControllers(); + // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle + builder.Services.AddEndpointsApiExplorer(); + builder.Services.AddSwaggerGen(); + + builder.Services.AddPipeAndFilter( + PipeAndFilter.New() + .AddPipe(ExecPipe) + .Build("opc1")); + + builder.Services.AddPipeAndFilter( + PipeAndFilter.New() + .AddPipe(ExecPipe) + .AddPipe(ExecPipe) + .Build("opc2")); + + var app = builder.Build(); + + // Configure the HTTP request pipeline. + if (app.Environment.IsDevelopment()) + { + app.UseSwagger(); + app.UseSwaggerUI(); + } + + app.UseHttpsRedirection(); + + app.UseAuthorization(); + + + app.MapControllers(); + + app.Run(); + } + + private static Task ExecPipe(EventPipe pipe, CancellationToken token) + { + pipe.ChangeContract((contract) => + { + contract.TemperatureC += 10; + }); + return Task.CompletedTask; + } + } +} \ No newline at end of file diff --git a/Samples/SampleApi/Properties/launchSettings.json b/Samples/SampleApi/Properties/launchSettings.json new file mode 100644 index 0000000..b370aea --- /dev/null +++ b/Samples/SampleApi/Properties/launchSettings.json @@ -0,0 +1,41 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:49906", + "sslPort": 44341 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5223", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7072;http://localhost:5223", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/Samples/SampleApi/WeatherForecast.cs b/Samples/SampleApi/WeatherForecast.cs new file mode 100644 index 0000000..8193e8d --- /dev/null +++ b/Samples/SampleApi/WeatherForecast.cs @@ -0,0 +1,13 @@ +namespace WebApplication1 +{ + public class WeatherForecast + { + public DateOnly Date { get; set; } + + public int TemperatureC { get; set; } + + public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); + + public string? Summary { get; set; } + } +} \ No newline at end of file diff --git a/Samples/SampleApi/appsettings.Development.json b/Samples/SampleApi/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/Samples/SampleApi/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/Samples/SampleApi/appsettings.json b/Samples/SampleApi/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/Samples/SampleApi/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/Samples/PipeAndFilterSamples.csproj b/Samples/SampleConsole/PipeAndFilterSampleConsole.csproj similarity index 69% rename from Samples/PipeAndFilterSamples.csproj rename to Samples/SampleConsole/PipeAndFilterSampleConsole.csproj index 389f831..023048e 100644 --- a/Samples/PipeAndFilterSamples.csproj +++ b/Samples/SampleConsole/PipeAndFilterSampleConsole.csproj @@ -1,4 +1,4 @@ - + Exe @@ -8,7 +8,7 @@ - + diff --git a/Samples/Program.cs b/Samples/SampleConsole/Program.cs similarity index 96% rename from Samples/Program.cs rename to Samples/SampleConsole/Program.cs index 2662186..e0455af 100644 --- a/Samples/Program.cs +++ b/Samples/SampleConsole/Program.cs @@ -14,11 +14,8 @@ public static async Task Main() ResultPipeAndFilter pl; var contract = new MyClass { MyProperty = 10 }; - pl = await PipeAndFilter.Create() - .Init(contract) - .CorrelationId(null) - .Logger(null) - .MaxDegreeProcess(4) + + pl = await PipeAndFilter.New() .AddPipe(ExecPipe) .WithCondition(CondFalse, "LastPipe") .WithCondition(CondTrue, null) @@ -27,10 +24,15 @@ public static async Task Main() .AddPipe(ExecPipe100) .AddPipeTasks(AgregateTask) .WithCondition(CondTrue, null) + .MaxDegreeProcess(4) .AddTask(Task50) .AddTaskCondition(Task100, CondFalse) .AddTask(Task150) .AddPipe(ExecPipe, "LastPipe") + .BuildAndCreate() + .Init(contract) + .CorrelationId(null) + .Logger(null) .Run(); Console.WriteLine($"Contract value : {contract.MyProperty}"); diff --git a/Src/CommandsInterface/IPipeAndFilterBuild.cs b/Src/CommandsInterface/IPipeAndFilterBuild.cs new file mode 100644 index 0000000..6ee95d9 --- /dev/null +++ b/Src/CommandsInterface/IPipeAndFilterBuild.cs @@ -0,0 +1,27 @@ +// ******************************************************************************************** +// MIT LICENCE +// The maintenance and evolution is maintained by the PipeAndFilter project under MIT license +// ******************************************************************************************** + +namespace PipeFilterCore +{ + /// + /// Represents the commands for build a service and Create the instance to run. + /// + /// Type of contract. + public interface IPipeAndFilterBuild where T : class + { + /// + /// Build PipeAndFilter to add into ServiceCollection. + /// + /// The service Id. + /// + IPipeAndFilterServiceBuild Build(string? serviceId = null); + + /// + /// Build and create PipeAndFilter to run. + /// + /// + IPipeAndFilterRunService BuildAndCreate(); + } +} \ No newline at end of file diff --git a/Src/CommandsInterface/IPipeAndFilterConditionsService.cs b/Src/CommandsInterface/IPipeAndFilterConditionsService.cs new file mode 100644 index 0000000..fb58b09 --- /dev/null +++ b/Src/CommandsInterface/IPipeAndFilterConditionsService.cs @@ -0,0 +1,53 @@ +// ******************************************************************************************** +// MIT LICENCE +// The maintenance and evolution is maintained by the PipeAndFilter project under MIT license +// ******************************************************************************************** + +namespace PipeFilterCore +{ + /// + /// Represents commands for conditions. + /// + /// Type of contract. + public interface IPipeAndFilterConditionsService: IPipeAndFilterBuild where T : class + { + /// + /// Add new pipe. + /// + /// The handler pipe to execute. + /// + /// The unique alias for pipe. + ///
If the alias is omitted, the alias will be the handler name followed by the reference quantity (if any).
+ /// + /// Alias ​​is used to reference in another pipe. + /// + IPipeAndFilterService AddPipe(Func, CancellationToken, Task> command, string? alias = null); + + /// + /// Add new pipe aggregate tasks. + /// + /// The handler pipe aggregate to execute. + ///
The handler command will run after all tasks are executed.
+ /// + /// + /// The unique alias for pipe. + ///
If the alias is omitted, the alias will be the handler name followed by the reference quantity (if any).
+ /// + /// Alias ​​is used to reference in another pipe. + /// + IPipeAndFilterTasksService AddPipeTasks(Func, CancellationToken, Task> command, string? alias = null); + + /// + /// Add new condition. + /// + /// The handle condition to execute. + /// + /// The alias to another pipe. + ///
If condition not have link to another pipe, the value must be null.
+ /// + /// The name for condition(optional). + /// + IPipeAndFilterConditionsService WithCondition(Func, CancellationToken, ValueTask> condition, string? aliasgoto, string? namecondition = null); + } + +} diff --git a/Src/CommandsInterface/IPipeAndFilterCreateService.cs b/Src/CommandsInterface/IPipeAndFilterCreateService.cs new file mode 100644 index 0000000..0e3f8ed --- /dev/null +++ b/Src/CommandsInterface/IPipeAndFilterCreateService.cs @@ -0,0 +1,40 @@ +// ******************************************************************************************** +// MIT LICENCE +// The maintenance and evolution is maintained by the PipeAndFilter project under MIT license +// ******************************************************************************************** + +namespace PipeFilterCore +{ + /// + /// Represents the commands for Pipes. + /// + /// Type of contract. + public interface IPipeAndFilterCreateService: IPipeAndFilterBuild where T : class + { + /// + /// Add new pipe. + /// + /// The handler pipe to execute. + /// + /// The unique alias for pipe. + ///
If the alias is omitted, the alias will be the handler name followed by the reference quantity (if any).
+ /// + /// Alias ​​is used to reference in another pipe. + /// + IPipeAndFilterService AddPipe(Func, CancellationToken, Task> command, string? alias = null); + + /// + /// Add new pipe aggregate tasks. + /// + /// The handler pipe aggregate to execute. + ///
The handler command will run after all tasks are executed.
+ /// + /// + /// The unique alias for pipe. + ///
If the alias is omitted, the alias will be the handler name followed by the reference quantity (if any).
+ /// + /// Alias ​​is used to reference in another pipe. + /// + IPipeAndFilterTasksService AddPipeTasks(Func, CancellationToken, Task> command, string? alias = null); + } +} diff --git a/Src/CommandsInterface/IPipeAndFilterRun.cs b/Src/CommandsInterface/IPipeAndFilterRun.cs new file mode 100644 index 0000000..5c6f6ea --- /dev/null +++ b/Src/CommandsInterface/IPipeAndFilterRun.cs @@ -0,0 +1,20 @@ +// ******************************************************************************************** +// MIT LICENCE +// The maintenance and evolution is maintained by the PipeAndFilter project under MIT license +// ******************************************************************************************** + +namespace PipeFilterCore +{ + /// + /// Represents the command for Run. + /// + /// Type of contract. + public interface IPipeAndFilterRun where T : class + { + /// + /// Execute PipeAndFilter. + /// + /// + ValueTask> Run(CancellationToken? cancellation = null); + } +} diff --git a/Src/CommandsInterface/IPipeAndFilterRunService.cs b/Src/CommandsInterface/IPipeAndFilterRunService.cs new file mode 100644 index 0000000..c7c494f --- /dev/null +++ b/Src/CommandsInterface/IPipeAndFilterRunService.cs @@ -0,0 +1,43 @@ +// ******************************************************************************************** +// MIT LICENCE +// The maintenance and evolution is maintained by the PipeAndFilter project under MIT license +// ******************************************************************************************** + +using Microsoft.Extensions.Logging; + +namespace PipeFilterCore +{ + /// + /// Represents commands for initialization and run. + /// + /// Type of contract. + public interface IPipeAndFilterRunService: IPipeAndFilterRun where T : class + { + /// + /// The service id for this type. + /// + string? ServiceId { get; } + + /// + /// Initial contract value. + /// + /// The contract. + /// + IPipeAndFilterRunService Init(T contract); + + /// + /// The Correlation Id. + /// + /// Correlation Id value. + /// + IPipeAndFilterRunService CorrelationId(string? value); + + /// + /// The logger handler. + /// + /// logger handler value. + /// + IPipeAndFilterRunService Logger(ILogger? value); + + } +} \ No newline at end of file diff --git a/Src/Control/IPipeAndFilter.cs b/Src/CommandsInterface/IPipeAndFilterService.cs similarity index 67% rename from Src/Control/IPipeAndFilter.cs rename to Src/CommandsInterface/IPipeAndFilterService.cs index 8916f2f..87ed21a 100644 --- a/Src/Control/IPipeAndFilter.cs +++ b/Src/CommandsInterface/IPipeAndFilterService.cs @@ -6,10 +6,10 @@ namespace PipeFilterCore { /// - /// Represents the commands for pipe. + /// Represents the commands for pipes. /// /// Type of contract. - public interface IPipeAndFilter where T : class + public interface IPipeAndFilterService : IPipeAndFilterBuild where T : class { /// /// Add new pipe. @@ -20,8 +20,8 @@ public interface IPipeAndFilter where T : class ///
If the alias is omitted, the alias will be the handler name followed by the reference quantity (if any).
/// /// Alias ​​is used to reference in another pipe. - /// - IPipeAndFilter AddPipe(Func, CancellationToken, Task> command, string? alias = null); + /// + IPipeAndFilterService AddPipe(Func, CancellationToken, Task> command, string? alias = null); /// /// Add new pipe aggregate tasks. @@ -34,8 +34,8 @@ public interface IPipeAndFilter where T : class ///
If the alias is omitted, the alias will be the handler name followed by the reference quantity (if any).
/// /// Alias ​​is used to reference in another pipe. - /// - IPipeAndFilterTasks AddPipeTasks(Func, CancellationToken, Task> command, string? alias = null); + /// + IPipeAndFilterTasksService AddPipeTasks(Func, CancellationToken, Task> command, string? alias = null); /// /// Add new condition. @@ -46,14 +46,9 @@ public interface IPipeAndFilter where T : class ///
If condition not have link to another pipe, the value must be null.
/// /// The name for condition(optional). - /// - IPipeAndFilterConditions WithCondition(Func, CancellationToken, ValueTask> condition, string? aliasgoto, string? namecondition = null); + /// + IPipeAndFilterConditionsService WithCondition(Func, CancellationToken, ValueTask> condition, string? aliasgoto, string? namecondition = null); - /// - /// Execute PipeAndFilter. - /// - /// - ValueTask> Run(); } -} \ No newline at end of file +} diff --git a/Src/CommandsInterface/IPipeAndFilterServiceBuild.cs b/Src/CommandsInterface/IPipeAndFilterServiceBuild.cs new file mode 100644 index 0000000..07dff2a --- /dev/null +++ b/Src/CommandsInterface/IPipeAndFilterServiceBuild.cs @@ -0,0 +1,26 @@ +// ******************************************************************************************** +// MIT LICENCE +// The maintenance and evolution is maintained by the PipeAndFilter project under MIT license +// ******************************************************************************************** +namespace PipeFilterCore +{ + + /// + /// Represents the commands for create a instance. + /// + /// Type of contract. + + public interface IPipeAndFilterServiceBuild where T : class + { + /// + /// The service id for this type. + /// + string? ServiceId { get; } + + /// + /// Create a instance. + /// + /// + IPipeAndFilterRunService Create(); + } +} diff --git a/Src/CommandsInterface/IPipeAndFilterTasksService.cs b/Src/CommandsInterface/IPipeAndFilterTasksService.cs new file mode 100644 index 0000000..9cb78bd --- /dev/null +++ b/Src/CommandsInterface/IPipeAndFilterTasksService.cs @@ -0,0 +1,82 @@ +// ******************************************************************************************** +// MIT LICENCE +// The maintenance and evolution is maintained by the PipeAndFilter project under MIT license +// ******************************************************************************************** + +namespace PipeFilterCore +{ + /// + /// Represents commands for task. + /// + /// Type of contract. + public interface IPipeAndFilterTasksService: IPipeAndFilterBuild where T : class + { + /// + /// Add new pipe. + /// + /// The handler pipe to execute. + /// + /// The unique alias for pipe. + ///
If the alias is omitted, the alias will be the handler name followed by the reference quantity (if any).
+ /// + /// Alias ​​is used to reference in another pipe. + /// + IPipeAndFilterService AddPipe(Func, CancellationToken, Task> command, string? alias = null); + + /// + /// Add new pipe aggregate tasks. + /// + /// The handler pipe aggregate to execute. + ///
The handler command will run after all tasks are executed.
+ /// + /// + /// The unique alias for pipe. + ///
If the alias is omitted, the alias will be the handler name followed by the reference quantity (if any).
+ /// + /// Alias ​​is used to reference in another pipe. + /// + IPipeAndFilterTasksService AddPipeTasks(Func, CancellationToken, Task> command, string? alias = null); + + /// + /// Add new task (execution in parallel) through pipe. + /// + /// The handler task to execute. + /// The name for task (optional). + /// + IPipeAndFilterTasksService AddTask(Func, CancellationToken, Task> command, string? nametask = null); + + /// + /// Maximum number of concurrent tasks enable. + /// + /// Number of concurrent tasks. + /// + /// The default value is number of processors. + /// + /// + IPipeAndFilterTasksService MaxDegreeProcess(int value); + + + /// + /// Add new task (execution in parallel) through pipe with a condition. + /// + /// The handler task to execute. + /// The handler task to condition. + /// The name for task (optional). + /// The name for condition (optional). + /// + IPipeAndFilterTasksService AddTaskCondition(Func, CancellationToken, Task> command, Func, CancellationToken, ValueTask> condition, string? nametask = null, string? namecondition = null); + + /// + /// Add new condition. + /// + /// The handle condition to execute. + /// + /// The alias to another pipe. + ///
If condition not have link to another pipe, the value must be null.
+ /// + /// The name for condition(optional). + /// + IPipeAndFilterTasksService WithCondition(Func, CancellationToken, ValueTask> condition, string? aliasgoto, string? namecondition = null); + + } +} diff --git a/Src/CommandsInterface/internal/IPipeAndFilterOptions.cs b/Src/CommandsInterface/internal/IPipeAndFilterOptions.cs new file mode 100644 index 0000000..dd66b4e --- /dev/null +++ b/Src/CommandsInterface/internal/IPipeAndFilterOptions.cs @@ -0,0 +1,23 @@ +// ******************************************************************************************** +// MIT LICENCE +// The maintenance and evolution is maintained by the PipeAndFilter project under MIT license +// ******************************************************************************************** + + +namespace PipeFilterCore.CommandsInterface +{ + internal interface IPipeAndFilterOptions where T : class + { + string? ServiceId { get; } + Dictionary AliasToId { get; } + Dictionary IdToAlias { get; } + Dictionary MaxDegreeProcess { get; } + Dictionary, CancellationToken, Task> pipehandle, + bool aggregateTasks, + List> precondhandle, + List status, + List<(string Id, Func, CancellationToken, Task> TaskHandle, PipeCondition? TaskCondition, string? NameTask, string? NameCondition)> tasks)> Pipes { get; } + + } +} diff --git a/Src/Control/EventPipe.cs b/Src/Control/EventPipe.cs index 5feaa93..1e1cadf 100644 --- a/Src/Control/EventPipe.cs +++ b/Src/Control/EventPipe.cs @@ -57,7 +57,7 @@ public EventPipe(string? cid, ILogger logger, Action> changecontract, } /// - /// The values saved ​​associated with pipes + /// The values saved ​​associated with pipes. /// /// /// The values ​​are serialized in json. @@ -82,12 +82,12 @@ public EventPipe(string? cid, ILogger logger, Action> changecontract, /// - /// The log handler + /// The log handler. /// public ILogger Logger { get; } /// - /// The Correlation Id + /// The Correlation Id. /// public string? CorrelationId { get; } @@ -111,7 +111,6 @@ public void EndPipeAndFilter() /// The action to change value. /// /// The action will only be executed if the contract exists. - ///
See .
///
public void ChangeContract(Action action) { @@ -134,7 +133,7 @@ public void SaveValue(T1 value) } /// - /// Remove a value associated with this pipe or task . + /// Remove a value associated with this pipe or task. /// public void RemoveSavedValue() { diff --git a/Src/Control/HandlerType.cs b/Src/Control/HandlerType.cs index 82616d9..c78f1c0 100644 --- a/Src/Control/HandlerType.cs +++ b/Src/Control/HandlerType.cs @@ -37,6 +37,6 @@ public enum HandlerType /// /// Type condition task. /// - ConditionTask, + ConditionTask } } diff --git a/Src/Control/IPipeAndFilterConditions.cs b/Src/Control/IPipeAndFilterConditions.cs deleted file mode 100644 index b1cc0be..0000000 --- a/Src/Control/IPipeAndFilterConditions.cs +++ /dev/null @@ -1,44 +0,0 @@ -// ******************************************************************************************** -// MIT LICENCE -// The maintenance and evolution is maintained by the PipeAndFilter project under MIT license -// ******************************************************************************************** - -namespace PipeFilterCore -{ - /// - /// Represents command for conditions - /// - /// Type of contract - public interface IPipeAndFilterConditions where T : class - { - /// - /// Add new pipe. - /// - /// The handler pipe to execute. - /// - /// The unique alias for pipe. - ///
If the alias is omitted, the alias will be the handler name followed by the reference quantity (if any).
- /// - /// Alias ​​is used to reference in another pipe. - /// - IPipeAndFilter AddPipe(Func, CancellationToken, Task> command, string? alias = null); - - /// - /// Add new condition. - /// - /// The handle condition to execute. - /// - /// The alias to another pipe. - ///
If condition not have link to another pipe, the value must be null.
- /// - /// The name for condition(optional). - /// - IPipeAndFilterConditions WithCondition(Func, CancellationToken, ValueTask> condition, string? aliasgoto, string? namecondition = null); - - /// - /// Execute the PipeAndFilter - /// - /// - ValueTask> Run(); - } -} diff --git a/Src/Control/IPipeAndFilterInit.cs b/Src/Control/IPipeAndFilterInit.cs deleted file mode 100644 index 7ef0b62..0000000 --- a/Src/Control/IPipeAndFilterInit.cs +++ /dev/null @@ -1,75 +0,0 @@ -// ******************************************************************************************** -// MIT LICENCE -// The maintenance and evolution is maintained by the PipeAndFilter project under MIT license -// ******************************************************************************************** - -using Microsoft.Extensions.Logging; - -namespace PipeFilterCore -{ - /// - /// Represents command for initialization - /// - /// Type of contract - public interface IPipeAndFilterInit where T : class - { - /// - /// Initial contract value. - /// - /// The contract. - /// - IPipeAndFilterInit Init(T contract); - - /// - /// Maximum number of concurrent tasks enable. - /// - /// Number of concurrent tasks. - /// - /// The default value is number of processors. - /// - /// - IPipeAndFilterInit MaxDegreeProcess(int value); - - /// - /// The Correlation Id - /// - /// Correlation Id value - /// - IPipeAndFilterInit CorrelationId(string? value); - - /// - /// The logger handler - /// - /// logger handler value - /// - IPipeAndFilterInit Logger(ILogger? value); - - - /// - /// Add new pipe. - /// - /// The handler pipe to execute. - /// - /// The unique alias for pipe. - ///
If the alias is omitted, the alias will be the handler name followed by the reference quantity (if any).
- /// - /// Alias ​​is used to reference in another pipe. - /// - IPipeAndFilter AddPipe(Func, CancellationToken, Task> command, string? alias = null); - - /// - /// Add new pipe aggregate tasks. - /// - /// The handler pipe aggregate to execute. - ///
The handler command will run after all tasks are executed.
- /// - /// - /// The unique alias for pipe. - ///
If the alias is omitted, the alias will be the handler name followed by the reference quantity (if any).
- /// - /// Alias ​​is used to reference in another pipe. - /// - IPipeAndFilterTasks AddPipeTasks(Func, CancellationToken, Task> command, string? alias = null); - - } -} \ No newline at end of file diff --git a/Src/Control/IPipeAndFilterTasks.cs b/Src/Control/IPipeAndFilterTasks.cs deleted file mode 100644 index f49dab7..0000000 --- a/Src/Control/IPipeAndFilterTasks.cs +++ /dev/null @@ -1,63 +0,0 @@ -// ******************************************************************************************** -// MIT LICENCE -// The maintenance and evolution is maintained by the PipeAndFilter project under MIT license -// ******************************************************************************************** - -namespace PipeFilterCore -{ - /// - /// Represents commands for task - /// - /// Type of contract - public interface IPipeAndFilterTasks where T : class - { - /// - /// Add new pipe. - /// - /// The handler pipe to execute. - /// - /// The unique alias for pipe. - ///
If the alias is omitted, the alias will be the handler name followed by the reference quantity (if any).
- /// - /// Alias ​​is used to reference in another pipe. - /// - IPipeAndFilter AddPipe(Func, CancellationToken, Task> command, string? alias = null); - - /// - /// Add new condition. - /// - /// The handle condition to execute. - /// - /// The alias to another pipe. - ///
If condition not have link to another pipe, the value must be null.
- /// - /// The name for condition(optional). - /// - IPipeAndFilterTasks WithCondition(Func, CancellationToken, ValueTask> condition, string? aliasgoto, string? namecondition = null); - - /// - /// Add new task (execution in parallel) through pipe. - /// - /// The handler task to execute. - /// The name for task (optional). - /// - IPipeAndFilterTasks AddTask(Func, CancellationToken, Task> command, string? nametask = null); - - /// - /// Add new task (execution in parallel) through pipe with a condition. - /// - /// The handler task to execute. - /// The handler task to condition. - /// The name for task (optional). - /// The name for condition (optional). - /// - IPipeAndFilterTasks AddTaskCondition(Func, CancellationToken, Task> command, Func, CancellationToken, ValueTask> condition, string? nametask = null, string? namecondition = null); - - - /// - /// Execute the PipeAndFilter - /// - /// - ValueTask> Run(); - } -} \ No newline at end of file diff --git a/Src/Control/PipeAndFilterCreator.cs b/Src/Control/PipeAndFilterCreator.cs new file mode 100644 index 0000000..fc63e2b --- /dev/null +++ b/Src/Control/PipeAndFilterCreator.cs @@ -0,0 +1,25 @@ +// ******************************************************************************************** +// MIT LICENCE +// The maintenance and evolution is maintained by the PipeAndFilter project under MIT license +// ******************************************************************************************** + +using PipeFilterCore.Control; + +namespace PipeFilterCore +{ + /// + /// Represents PipeAndFilter Creator. + /// + public static class PipeAndFilter + { + /// + /// Create PipeAndFilter service. + /// + /// + /// + public static IPipeAndFilterCreateService New() where T : class + { + return new PipeAndFilterBuild(); + } + } +} \ No newline at end of file diff --git a/Src/Control/PipeAndFilterException.cs b/Src/Control/PipeAndFilterException.cs index 3c3c0b3..100df61 100644 --- a/Src/Control/PipeAndFilterException.cs +++ b/Src/Control/PipeAndFilterException.cs @@ -15,7 +15,7 @@ namespace PipeFilterCore public class PipeAndFilterException : Exception { /// - /// The default status for initialize + /// The default status for initialize. /// public static readonly PipeStatus StatusInit = new(HandlerType.Pipe, TaskStatus.Created, @@ -31,9 +31,9 @@ private PipeAndFilterException() } /// - /// Create PipeAndFilter-Exception + /// Create PipeAndFilter-Exception. /// - ///The status of step (pipe, condition or task) + ///The status of step (pipe, condition or task). ///The message that describes the error. public PipeAndFilterException(PipeStatus status, string? message) : base(message) { @@ -41,11 +41,11 @@ public PipeAndFilterException(PipeStatus status, string? message) : base(message } /// - /// Create PipeAndFilter-Exception with innerException + /// Create PipeAndFilter-Exception with innerException. /// - ///The status of step (pipe, condition or task) + ///The status of step (pipe, condition or task). ///The message that describes the error. - ///The exception that is the cause of the current exception, or a null reference + ///The exception that is the cause of the current exception, or a null reference. public PipeAndFilterException(PipeStatus status, string? message, Exception? innerException) : base(message, innerException) { Status = status; diff --git a/Src/Control/PipeAndFilterExtension.cs b/Src/Control/PipeAndFilterExtension.cs deleted file mode 100644 index 489cd7a..0000000 --- a/Src/Control/PipeAndFilterExtension.cs +++ /dev/null @@ -1,27 +0,0 @@ -// ******************************************************************************************** -// MIT LICENCE -// The maintenance and evolution is maintained by the PipeAndFilter project under MIT license -// ******************************************************************************************** - -namespace PipeFilterCore -{ - /// - /// Represents PipeAndFilter Extension. - /// - public static class PipeAndFilter - { - /// - /// Create PipeAndFilter. - /// - /// The - /// Type of return.] - /// - /// If ommited the value is 'CancellationToken.None'. - /// - /// - public static IPipeAndFilterInit Create(CancellationToken? cts = null) where T : class - { - return new PipeAndFilterControl(cts??CancellationToken.None); - } - } -} \ No newline at end of file diff --git a/Src/Control/PipeRanStatus.cs b/Src/Control/PipeRanStatus.cs index 0de093b..e988bc1 100644 --- a/Src/Control/PipeRanStatus.cs +++ b/Src/Control/PipeRanStatus.cs @@ -27,9 +27,9 @@ public PipeRanStatus() /// /// Create PipeRanStatus (Only internal use or Unit-Test). /// - /// The pipe Id - /// The pipe alias - /// The detailed status of all runs + /// The pipe Id. + /// The pipe alias. + /// The detailed status of all runs. public PipeRanStatus(string id, string? alias, IEnumerable details) { Id = id; diff --git a/Src/Control/ResultPipeAndFilter.cs b/Src/Control/ResultPipeAndFilter.cs index f0e575e..bf356ed 100644 --- a/Src/Control/ResultPipeAndFilter.cs +++ b/Src/Control/ResultPipeAndFilter.cs @@ -8,17 +8,17 @@ namespace PipeFilterCore { /// - /// Represents the result of PipeAndFilter + /// Represents the result of PipeAndFilter. /// public readonly struct ResultPipeAndFilter where T : class { /// - /// Create Result of PipeAndFilter + /// Create Result of PipeAndFilter. /// /// /// Do not use this constructor! /// - /// Message error + /// Message error. public ResultPipeAndFilter() { throw new PipeAndFilterException( @@ -42,7 +42,7 @@ public ResultPipeAndFilter(T? value, bool aborted, PipeAndFilterException? excep } /// - /// The Contract value + /// The Contract value. /// public T? Value { get; } @@ -57,7 +57,7 @@ public ResultPipeAndFilter(T? value, bool aborted, PipeAndFilterException? excep public PipeAndFilterException? Exception { get; } /// - /// The status details of all pipes + /// The status details of all pipes. /// public ImmutableArray Status { get; } diff --git a/Src/Control/internal/PipeAndFilterBuild.cs b/Src/Control/internal/PipeAndFilterBuild.cs new file mode 100644 index 0000000..a668d40 --- /dev/null +++ b/Src/Control/internal/PipeAndFilterBuild.cs @@ -0,0 +1,278 @@ +// ******************************************************************************************** +// MIT LICENCE +// The maintenance and evolution is maintained by the PipeAndFilter project under MIT license +// ******************************************************************************************** + +namespace PipeFilterCore.Control +{ + /// + /// Represents the commands of the PipeAndFilter definition. + /// + /// Type of contract. + internal class PipeAndFilterBuild : + IPipeAndFilterCreateService, + IPipeAndFilterService, + IPipeAndFilterConditionsService, + IPipeAndFilterTasksService + where T : class + { + internal readonly Dictionary _aliasToId = new(); + internal readonly Dictionary _idToAlias = new(); + internal readonly Dictionary _maxDegreeProcess = new(); + internal readonly Dictionary, CancellationToken, Task> pipehandle, + bool aggregateTasks, + List> precondhandle, + List status, + List<(string Id, Func, CancellationToken, Task> TaskHandle, PipeCondition? TaskCondition, string? NameTask, string? NameCondition)> tasks)> _pipes = new(); + + private readonly int _defaultMaxProcess = Environment.ProcessorCount; + private string? _currentPipe; + + #region IPipeAndFilterCreateService + + IPipeAndFilterService IPipeAndFilterCreateService.AddPipe(Func, CancellationToken, Task> command, string? alias) + { + SharedAddPipeTasks(command, alias, false); + return this; + } + + IPipeAndFilterTasksService IPipeAndFilterCreateService.AddPipeTasks(Func, CancellationToken, Task> command, string? alias) + { + SharedAddPipeTasks(command, alias, true); + return this; + } + + #endregion + + #region IPipeAndFilterService + + IPipeAndFilterService IPipeAndFilterService.AddPipe(Func, CancellationToken, Task> command, string? alias) + { + SharedAddPipeTasks(command, alias, false); + return this; + } + + IPipeAndFilterTasksService IPipeAndFilterService.AddPipeTasks(Func, CancellationToken, Task> command, string? alias) + { + SharedAddPipeTasks(command, alias, true); + return this; + } + + IPipeAndFilterConditionsService IPipeAndFilterService.WithCondition(Func, CancellationToken, ValueTask> condition, string? aliasgoto, string? namecondition) + { + SharedWithCondition(condition,aliasgoto, namecondition); + return this; + } + + #endregion + + #region IPipeAndFilterConditionsService + + IPipeAndFilterService IPipeAndFilterConditionsService.AddPipe(Func, CancellationToken, Task> command, string? alias) + { + SharedAddPipeTasks(command, alias, false); + return this; + } + + IPipeAndFilterTasksService IPipeAndFilterConditionsService.AddPipeTasks(Func, CancellationToken, Task> command, string? alias) + { + SharedAddPipeTasks(command, alias, true); + return this; + } + + IPipeAndFilterConditionsService IPipeAndFilterConditionsService.WithCondition(Func, CancellationToken, ValueTask> condition, string? aliasgoto, string? namecondition) + { + SharedWithCondition(condition, aliasgoto, namecondition); + return this; + } + + #endregion + + #region IPipeAndFilterTasksService + + IPipeAndFilterTasksService IPipeAndFilterTasksService.AddTask(Func, CancellationToken, Task> command, string? nametask) + { + SharedAddTask(command, null, nametask, null); + return this; + } + + IPipeAndFilterTasksService IPipeAndFilterTasksService.AddTaskCondition(Func, CancellationToken, Task> command, Func, CancellationToken, ValueTask> condition, string? nametask, string? namecondition) + { + SharedAddTask(command, condition, nametask, namecondition); + return this; + } + + IPipeAndFilterTasksService IPipeAndFilterTasksService.MaxDegreeProcess(int value) + { + if (value < 0) + { + throw new PipeAndFilterException( + PipeAndFilterException.StatusInit, + "MaxDegreeProcess must be greater than zero"); + } + if (string.IsNullOrEmpty(_currentPipe)) + { + throw new PipeAndFilterException( + PipeAndFilterException.StatusInit, + "Pipe not exist to set MaxDegreeProcess"); + } + if (!_pipes[_currentPipe].aggregateTasks) + { + throw new PipeAndFilterException( + PipeAndFilterException.StatusInit, + "Pipe not aggregate tasks"); + } + _maxDegreeProcess[_currentPipe!] = value; + return this; + } + + IPipeAndFilterTasksService IPipeAndFilterTasksService.WithCondition(Func, CancellationToken, ValueTask> condition, string? aliasgoto, string? namecondition) + { + SharedWithCondition(condition, aliasgoto, namecondition); + return this; + } + + IPipeAndFilterService IPipeAndFilterTasksService.AddPipe(Func, CancellationToken, Task> command, string? alias) + { + SharedAddPipeTasks(command, alias, false); + return this; + } + + IPipeAndFilterTasksService IPipeAndFilterTasksService.AddPipeTasks(Func, CancellationToken, Task> command, string? alias) + { + SharedAddPipeTasks(command, alias, true); + return this; + } + + #endregion + + #region IPipeAndFilterBuild + + IPipeAndFilterServiceBuild IPipeAndFilterBuild.Build(string? serviceId) + { + if (_pipes.Count == 0) + { + throw new PipeAndFilterException( + PipeAndFilterException.StatusInit, + "Not pipes to run"); + } + foreach (var item in _pipes.Where(x => x.Value.precondhandle.Any())) + { + foreach (var precond in item.Value.precondhandle.Where(x => !string.IsNullOrEmpty(x.GotoId))) + { + var id = _aliasToId[precond.GotoId!]; + if (!_pipes.ContainsKey(id)) + { + throw new PipeAndFilterException( + PipeAndFilterException.StatusInit, + $"Condition {precond.Name ?? ""} with invalid go to pipe Alias: {precond.GotoId}"); + } + } + } + return new PipeAndFilterService(serviceId, this); + } + + IPipeAndFilterRunService IPipeAndFilterBuild.BuildAndCreate() + { + return new PipeAndFilterControl(new PipeAndFilterService(null, this)); + } + + + #endregion + + private void SharedAddPipeTasks(Func, CancellationToken, Task> command, string? alias, bool agregatetask) + { + var id = Guid.NewGuid().ToString(); + if (command == null) + { + throw new PipeAndFilterException( + PipeAndFilterException.StatusInit, + "command cannot be null"); + } + if (alias == null) + { + var seq = 1; + var name = command.Method.Name; + alias = name; + while (_aliasToId.ContainsKey(alias)) + { + alias = $"{name}({seq})"; + } + } + if (!_aliasToId.TryAdd(alias, id)) + { + throw new PipeAndFilterException( + PipeAndFilterException.StatusInit, + "Alias already exists"); + } + _idToAlias.Add(id, alias); + + if (agregatetask) + { + _maxDegreeProcess.Add(id, _defaultMaxProcess); + } + + if (!_pipes.TryAdd(id, (command, agregatetask, new(), new(), new()))) + { + throw new PipeAndFilterException( + PipeAndFilterException.StatusInit, + "idpipe already exists"); + } + _currentPipe = id; + } + + private void SharedWithCondition(Func, CancellationToken, ValueTask> condition, string? aliasgoto, string? namecondition) + { + if (condition == null) + { + throw new PipeAndFilterException( + PipeAndFilterException.StatusInit, + "condition cannot be null"); + } + if (string.IsNullOrEmpty(namecondition)) + { + namecondition = condition.Method.Name; + } + _pipes[_currentPipe!].precondhandle.Add(new PipeCondition(condition, aliasgoto, namecondition)); + } + + private void SharedAddTask(Func, CancellationToken, Task> command, Func, CancellationToken, ValueTask>? condition, string? nametask, string? namecond) + { + var id = Guid.NewGuid().ToString(); + if (string.IsNullOrEmpty(_currentPipe)) + { + throw new PipeAndFilterException( + PipeAndFilterException.StatusInit, + "Pipe not exist to add task"); + } + if (!_pipes[_currentPipe].aggregateTasks) + { + throw new PipeAndFilterException( + PipeAndFilterException.StatusInit, + "Pipe not aggregate tasks"); + } + if (command == null) + { + throw new PipeAndFilterException( + PipeAndFilterException.StatusInit, + "command cannot be null"); + } + if (condition != null && string.IsNullOrEmpty(namecond)) + { + namecond = condition.Method.Name; + } + if (string.IsNullOrEmpty(nametask)) + { + nametask = command.Method.Name; + } + PipeCondition? pipecond = null; + if (condition != null) + { + pipecond = new PipeCondition(condition, null, nametask); + } + _pipes[_currentPipe].tasks.Add((id, command, pipecond, nametask, namecond)); + } + + } +} diff --git a/Src/Control/PipeAndFilterControl.cs b/Src/Control/internal/PipeAndFilterControl.cs similarity index 63% rename from Src/Control/PipeAndFilterControl.cs rename to Src/Control/internal/PipeAndFilterControl.cs index eedfe5d..da46a4f 100644 --- a/Src/Control/PipeAndFilterControl.cs +++ b/Src/Control/internal/PipeAndFilterControl.cs @@ -3,191 +3,77 @@ // The maintenance and evolution is maintained by the PipeAndFilter project under MIT license // ******************************************************************************************** +using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; +using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; +using PipeFilterCore.CommandsInterface; -namespace PipeFilterCore +namespace PipeFilterCore.Control { - internal class PipeAndFilterControl : IDisposable, IPipeAndFilterInit, IPipeAndFilter, IPipeAndFilterConditions, IPipeAndFilterTasks where T : class + internal class PipeAndFilterControl : IDisposable,IPipeAndFilterRunService where T : class { + private readonly IPipeAndFilterOptions _parameters; private readonly List _tasks = new(); private readonly object _lockObj = new(); + private readonly List _sequencePipes = new(); private readonly List<(string? Alias, string Id, string? Value)> _savedvalues = new(); private readonly List<(string? Alias, string Id, string? Value)> _savedtaskvalues = new(); - private readonly CancellationToken _ctstoken; - private readonly Dictionary _aliasToId = new(); - private readonly Dictionary _idToAlias = new(); - private readonly List _sequencePipes = new(); + private bool _disposed; + private CancellationTokenSource? _pipects; private ILogger _logger = NullLogger.Instance; private string? _cid; - - private bool _disposed; private PipeAndFilterException? _lastexception; - - private int _maxDegreeProcess = Environment.ProcessorCount; private T? _contract; - + private int _currentPipeIndex; private string? _currentPipe; private string? _prevPipe; - private bool _abort; private bool _finished; - private bool IsEnd => _finished || _abort || _pipects!.IsCancellationRequested; - private CancellationTokenSource? _pipects; - - private readonly Dictionary, CancellationToken, Task> pipehandle, - bool aggregateTasks, - List> precondhandle, - List status, - List<(string Id, Func, CancellationToken, Task> TaskHandle, PipeCondition? TaskCondition, string? NameTask, string? NameCondition)> tasks)> _pipes = new(); - - private int _currentPipeIndex; - - #region ctor - - private PipeAndFilterControl() + public PipeAndFilterControl(IPipeAndFilterOptions parameters) { - throw new PipeAndFilterException( - PipeAndFilterException.StatusInit, - "Invalid ctor PipeAndFilterControl"); + _parameters = parameters; } - public PipeAndFilterControl(CancellationToken cts) - { - _ctstoken = cts; - } + #region IPipeAndFilterRunService - #endregion + public string? ServiceId => _parameters.ServiceId; - #region IPipeAndFilterInit - - IPipeAndFilterInit IPipeAndFilterInit.Logger(ILogger? value) - { - _logger = value??NullLogger.Instance; - return this; - } - - IPipeAndFilterInit IPipeAndFilterInit.CorrelationId(string? value) + public IPipeAndFilterRunService CorrelationId(string? value) { _cid = value; return this; } - IPipeAndFilter IPipeAndFilterInit.AddPipe(Func, CancellationToken, Task> command, string? alias) - { - SharedAddPipe(command, alias, false); - return this; - } - - IPipeAndFilterTasks IPipeAndFilterInit.AddPipeTasks(Func, CancellationToken, Task> command, string? alias) - { - SharedAddPipe(command, alias, true); - return this; - } - - IPipeAndFilterInit IPipeAndFilterInit.Init(T contract) + public IPipeAndFilterRunService Init(T contract) { _contract = contract; return this; } - IPipeAndFilterInit IPipeAndFilterInit.MaxDegreeProcess(int value) + public IPipeAndFilterRunService Logger(ILogger? value) { - if (value < 0) - { - throw new PipeAndFilterException( - PipeAndFilterException.StatusInit, - "MaxDegreeProcess must be greater than zero"); - } - _maxDegreeProcess = value; + _logger = value ?? NullLogger.Instance; return this; } - #endregion - - #region IPipeAndFilter - - IPipeAndFilter IPipeAndFilter.AddPipe(Func, CancellationToken, Task> command, string? alias) + public async ValueTask> Run(CancellationToken? cancellation = null) { - SharedAddPipe(command, alias, false); - return this; - } - - IPipeAndFilterTasks IPipeAndFilter.AddPipeTasks(Func, CancellationToken, Task> command, string? alias) - { - SharedAddPipe(command, alias, true); - return this; - } - - async ValueTask> IPipeAndFilter.Run() - { - return await SharedRun(_ctstoken); - } - IPipeAndFilterConditions IPipeAndFilter.WithCondition(Func, CancellationToken, ValueTask> condition, string? aliasgoto, string? namecondition) - { - SharedWithCondition(condition, aliasgoto, namecondition); - return this; - } + _pipects = CancellationTokenSource.CreateLinkedTokenSource(cancellation??CancellationToken.None); - #endregion - - #region IPipeAndFilterConditions - - IPipeAndFilter IPipeAndFilterConditions.AddPipe(Func, CancellationToken, Task> command, string? alias) - { - SharedAddPipe(command, alias, false); - return this; - } - - IPipeAndFilterConditions IPipeAndFilterConditions.WithCondition(Func, CancellationToken, ValueTask> condition, string? aliasgoto, string? namecondition) - { - SharedWithCondition(condition, aliasgoto, namecondition); - return this; - } - - async ValueTask> IPipeAndFilterConditions.Run() - { - return await SharedRun(_ctstoken); - } - - #endregion - - #region IPipeAndFilterTasks - - IPipeAndFilter IPipeAndFilterTasks.AddPipe(Func, CancellationToken, Task> command, string? alias) - { - SharedAddPipe(command, alias, false); - return this; - } - - IPipeAndFilterTasks IPipeAndFilterTasks.AddTask(Func, CancellationToken, Task> command, string? name) - { - SharedAddTask(command,null, name, null); - return this; - } + InitControl(); - IPipeAndFilterTasks IPipeAndFilterTasks.AddTaskCondition(Func, CancellationToken, Task> command, Func, CancellationToken, ValueTask> condition, string? nametask, string? namecondition) - { - SharedAddTask(command, condition, nametask, namecondition); - return this; - } + var aux = await ExecutePipes(); - IPipeAndFilterTasks IPipeAndFilterTasks.WithCondition(Func, CancellationToken, ValueTask> condition, string? aliasgoto, string? namecondition) - { - SharedWithCondition(condition, aliasgoto, namecondition); - return this; - } + Dispose(); - async ValueTask> IPipeAndFilterTasks.Run() - { - return await SharedRun(_ctstoken); + return aux; } #endregion @@ -219,142 +105,9 @@ protected virtual void Dispose(bool disposing) #endregion - private void ChangeContract(Action eventchange) - { - lock (_lockObj) - { - if (_contract == null) - { - return; - } - eventchange(_contract); - } - } - - private void SharedAddPipe(Func, CancellationToken, Task> command, string? alias, bool agregatetask) - { - var id = Guid.NewGuid().ToString(); - if (command == null) - { - throw new PipeAndFilterException( - PipeAndFilterException.StatusInit, - "command cannot be null"); - } - if (alias == null) - { - var seq = 1; - var name = command.Method.Name; - alias = name; - while (_aliasToId.ContainsKey(alias)) - { - alias = $"{name}({seq})"; - } - } - if (!_aliasToId.TryAdd(alias, id)) - { - throw new PipeAndFilterException( - PipeAndFilterException.StatusInit, - "Alias already exists"); - } - _idToAlias.Add(id, alias); - - if (!_pipes.TryAdd(id, (command, agregatetask, new(), new(), new()))) - { - throw new PipeAndFilterException( - PipeAndFilterException.StatusInit, - "idpipe already exists"); - } - _currentPipe = id; - } - - private void SharedAddTask(Func, CancellationToken, Task> command, Func, CancellationToken, ValueTask>? condition, string? nametask, string? namecond) - { - var id = Guid.NewGuid().ToString(); - if (string.IsNullOrEmpty(_currentPipe)) - { - throw new PipeAndFilterException( - PipeAndFilterException.StatusInit, - "Pipe not exist to add task"); - } - if (!_pipes[_currentPipe].aggregateTasks) - { - throw new PipeAndFilterException( - PipeAndFilterException.StatusInit, - "Pipe not aggregate tasks"); - } - if (command == null) - { - throw new PipeAndFilterException( - PipeAndFilterException.StatusInit, - "command cannot be null"); - } - if (condition != null && string.IsNullOrEmpty(namecond)) - { - namecond = condition.Method.Name; - } - if (string.IsNullOrEmpty(nametask)) - { - nametask = command.Method.Name; - } - PipeCondition? pipecond = null; - if (condition != null) - { - pipecond = new PipeCondition(condition, null, nametask); - } - _pipes[_currentPipe].tasks.Add((id, command, pipecond, nametask, namecond)); - } - - private void SharedWithCondition(Func, CancellationToken, ValueTask> condition, string? aliasgoto, string? namecondition) - { - if (condition == null) - { - throw new PipeAndFilterException( - PipeAndFilterException.StatusInit, - "condition cannot be null"); - } - if (string.IsNullOrEmpty(namecondition)) - { - namecondition = condition.Method.Name; - } - _pipes[_currentPipe!].precondhandle.Add(new PipeCondition(condition, aliasgoto, namecondition)); - } - - private async ValueTask> SharedRun(CancellationToken cts) - { - - _pipects = CancellationTokenSource.CreateLinkedTokenSource(cts); - - InitControl(); - - var aux = await ExecutePipes(); - - Dispose(); - - return aux; - } - private void InitControl() { - if (_pipes.Count == 0) - { - throw new PipeAndFilterException( - PipeAndFilterException.StatusInit, - "Not pipes to run"); - } - _sequencePipes.AddRange(_pipes.Keys.ToArray()); - foreach (var item in _pipes.Where(x => x.Value.precondhandle.Any())) - { - foreach (var precond in item.Value.precondhandle.Where(x => !string.IsNullOrEmpty(x.GotoId))) - { - var id = _aliasToId[precond.GotoId!]; - if (!_pipes.ContainsKey(id)) - { - throw new PipeAndFilterException( - PipeAndFilterException.StatusInit, - $"Condition {precond.Name ?? ""} with invalid go to pipe Alias: {precond.GotoId}"); - } - } - } + _sequencePipes.AddRange(_parameters.Pipes.Keys.ToArray()); } private async ValueTask> ExecutePipes() @@ -372,18 +125,18 @@ private async ValueTask> ExecutePipes() try { _savedtaskvalues.Clear(); - if (_pipes[_currentPipe!].aggregateTasks) + if (_parameters.Pipes[_currentPipe!].aggregateTasks) { - await ExecuteTasksPipes(_pipes[_currentPipe!].tasks!); + await ExecuteTasksPipes(_parameters.Pipes[_currentPipe!].tasks!); } if (!IsEnd) { string? aliasprev = null; if (!string.IsNullOrEmpty(_prevPipe)) { - aliasprev = _idToAlias[_prevPipe]; + aliasprev = _parameters.IdToAlias[_prevPipe]; }; - string? aliascur = _idToAlias[_currentPipe!]; + string? aliascur = _parameters.IdToAlias[_currentPipe!]; var evt = new EventPipe( _cid, _logger, @@ -393,7 +146,7 @@ private async ValueTask> ExecutePipes() _prevPipe, _currentPipe!, aliasprev, aliascur); - await _pipes[_currentPipe!].pipehandle(evt, _pipects!.Token); + await _parameters.Pipes[_currentPipe!].pipehandle(evt, _pipects!.Token); sta = TaskStatus.RanToCompletion; elapsed = tm.Elapsed; EnsureResultEventPipe(_currentPipe!, evt); @@ -414,7 +167,7 @@ private async ValueTask> ExecutePipes() HandlerType.Pipe, sta, elapsed, - _idToAlias[_currentPipe!], + _parameters.IdToAlias[_currentPipe!], null, true), "Error handler Pipe", ex); @@ -422,11 +175,11 @@ private async ValueTask> ExecutePipes() _finished = true; } tm.Stop(); - _pipes[_currentPipe!].status.Add(new PipeStatus( + _parameters.Pipes[_currentPipe!].status.Add(new PipeStatus( HandlerType.Pipe, sta, elapsed, - _idToAlias[_currentPipe!], + _parameters.IdToAlias[_currentPipe!], null, true)); } @@ -452,17 +205,155 @@ private async ValueTask> ExecutePipes() _contract, _abort, _lastexception, - _pipes.Select(x => + _parameters.Pipes.Select(x => new PipeRanStatus( x.Key, - _idToAlias[x.Key], + _parameters.IdToAlias[x.Key], x.Value.status)).ToImmutableArray() ); } + private async Task NextPipe() + { + while (!IsEnd) + { + var isok = true; + foreach (var itemcond in _parameters.Pipes[_currentPipe!].precondhandle) + { + var condpipeType = string.IsNullOrEmpty(itemcond.GotoId) ? HandlerType.Condition : HandlerType.ConditionGoto; + var sta = TaskStatus.RanToCompletion; + string? aliasprev = null; + if (!string.IsNullOrEmpty(_prevPipe)) + { + aliasprev = _parameters.IdToAlias[_prevPipe]; + }; + string? aliascur = _parameters.IdToAlias[_currentPipe!]; + + var evt = new EventPipe( + _cid, + _logger, + ChangeContract!, + _savedvalues.ToImmutableArray(), + _savedtaskvalues.ToImmutableArray(), + _prevPipe, + _currentPipe!, + aliasprev, aliascur); + + var elapsed = TimeSpan.Zero; + var tm = Stopwatch.StartNew(); + try + { + isok = await itemcond.Handle!(evt, _pipects!.Token); + elapsed = tm.Elapsed; + EnsureResultEventPipe(_currentPipe!, evt); + } + catch (OperationCanceledException) + { + elapsed = tm.Elapsed; + sta = TaskStatus.Canceled; + _finished = true; + } + catch (Exception ex) + { + elapsed = tm.Elapsed; + sta = TaskStatus.Faulted; + _lastexception = new PipeAndFilterException( + new PipeStatus( + condpipeType, + sta, + elapsed, + itemcond.Name, + itemcond.GotoId, isok), + "Error handler condition", + ex); + _abort = true; + _finished = true; + _pipects!.Cancel(false); + } + tm.Stop(); + _parameters.Pipes[_currentPipe!].status.Add(new PipeStatus( + condpipeType, + sta, + elapsed, + itemcond.Name, + itemcond.GotoId, isok)); + if (!IsEnd) + { + if ((!isok && condpipeType == HandlerType.Condition) || (isok && condpipeType == HandlerType.ConditionGoto)) + { + if (!string.IsNullOrEmpty(itemcond.GotoId)) + { + _prevPipe = _currentPipe; + _currentPipe = _parameters.AliasToId[itemcond.GotoId]; + _currentPipeIndex = _sequencePipes.IndexOf(_currentPipe); + return; + } + _currentPipeIndex++; + if (_currentPipeIndex < _sequencePipes.Count) + { + _prevPipe = _currentPipe; + _currentPipe = _sequencePipes[_currentPipeIndex]; + } + else + { + _finished = true; + } + return; + } + } + } + if (isok) + { + break; + } + } + } + + private void EnsureResultEventPipe(string idpipe, EventPipe eventPipe) + { + if (eventPipe.FinishedPipeAndFilter) + { + _finished = true; + } + var alias = _parameters.IdToAlias[idpipe]; + if (eventPipe.ToRemove) + { + var index = _savedvalues.FindIndex(x => x.Id == idpipe); + if (index >= 0) + { + _savedvalues.RemoveAt(index); + } + } + else if (eventPipe.IsSaved) + { + var index = _savedvalues.FindIndex(x => x.Id == idpipe); + if (index >= 0) + { + _savedvalues[index] = (alias, idpipe, eventPipe.ValueToSave); + } + else + { + _savedvalues.Add((alias, idpipe, eventPipe.ValueToSave)); + } + } + } + + private void ChangeContract(Action eventchange) + { + lock (_lockObj) + { + if (_contract == null) + { + return; + } + eventchange(_contract); + } + } + private async Task ExecuteTasksPipes(List<(string Id, Func, CancellationToken, Task> TaskHandle, PipeCondition? TaskCondition, string? NameTask, string? NameCondition)> tasks) { var i = 0; + var maxDegreeProcess = _parameters.MaxDegreeProcess[_currentPipe!]; _savedtaskvalues.Clear(); var emptytask = _savedtaskvalues.ToImmutableArray(); do @@ -477,9 +368,9 @@ private async Task ExecuteTasksPipes(List<(string Id, Func, Cancell string? aliasprev = null; if (!string.IsNullOrEmpty(_prevPipe)) { - aliasprev = _idToAlias[_prevPipe]; + aliasprev = _parameters.IdToAlias[_prevPipe]; }; - string? aliascur = _idToAlias[_currentPipe!]; + string? aliascur = _parameters.IdToAlias[_currentPipe!]; var evt = new EventPipe( _cid, @@ -518,13 +409,13 @@ private async Task ExecuteTasksPipes(List<(string Id, Func, Cancell tasks[i].NameTask, null, isvalidtask), "Error handler Condition Task", - ex); + ex); _abort = true; _finished = true; _pipects!.Cancel(false); } tm.Stop(); - _pipes[_currentPipe!].status.Add(new PipeStatus( + _parameters.Pipes[_currentPipe!].status.Add(new PipeStatus( HandlerType.ConditionTask, sta, elapsed, @@ -553,9 +444,9 @@ private async Task ExecuteTasksPipes(List<(string Id, Func, Cancell taskname = tasks[index].NameTask; if (!string.IsNullOrEmpty(_prevPipe)) { - aliasprev = _idToAlias[_prevPipe]; + aliasprev = _parameters.IdToAlias[_prevPipe]; }; - aliascur = _idToAlias[_currentPipe!]; + aliascur = _parameters.IdToAlias[_currentPipe!]; evt = new EventPipe( _cid, _logger, @@ -608,7 +499,7 @@ private async Task ExecuteTasksPipes(List<(string Id, Func, Cancell tm.Stop(); lock (_lockObj) { - _pipes[_currentPipe!].status.Add(new PipeStatus( + _parameters.Pipes[_currentPipe!].status.Add(new PipeStatus( HandlerType.Task, sta, elapsed, @@ -623,7 +514,7 @@ private async Task ExecuteTasksPipes(List<(string Id, Func, Cancell degreecount++; } i++; - } while (!IsEnd && i < tasks.Count && degreecount < _maxDegreeProcess); + } while (!IsEnd && i < tasks.Count && degreecount < maxDegreeProcess); if (!IsEnd) { try @@ -645,131 +536,6 @@ private async Task ExecuteTasksPipes(List<(string Id, Func, Cancell } while (!IsEnd && i < tasks.Count); } - private async Task NextPipe() - { - while (!IsEnd) - { - var isok = true; - foreach (var itemcond in _pipes[_currentPipe!].precondhandle) - { - var condpipeType = string.IsNullOrEmpty(itemcond.GotoId) ? HandlerType.Condition : HandlerType.ConditionGoto; - var sta = TaskStatus.RanToCompletion; - string? aliasprev = null; - if (!string.IsNullOrEmpty(_prevPipe)) - { - aliasprev = _idToAlias[_prevPipe]; - }; - string? aliascur = _idToAlias[_currentPipe!]; - - var evt = new EventPipe( - _cid, - _logger, - ChangeContract!, - _savedvalues.ToImmutableArray(), - _savedtaskvalues.ToImmutableArray(), - _prevPipe, - _currentPipe!, - aliasprev, aliascur); - - var elapsed = TimeSpan.Zero; - var tm = Stopwatch.StartNew(); - try - { - isok = await itemcond.Handle!(evt, _pipects!.Token); - elapsed = tm.Elapsed; - EnsureResultEventPipe(_currentPipe!, evt); - } - catch (OperationCanceledException) - { - elapsed = tm.Elapsed; - sta = TaskStatus.Canceled; - _finished = true; - } - catch (Exception ex) - { - elapsed = tm.Elapsed; - sta = TaskStatus.Faulted; - _lastexception = new PipeAndFilterException( - new PipeStatus( - condpipeType, - sta, - elapsed, - itemcond.Name, - itemcond.GotoId, isok), - "Error handler condition", - ex); - _abort = true; - _finished = true; - _pipects!.Cancel(false); - } - tm.Stop(); - _pipes[_currentPipe!].status.Add(new PipeStatus( - condpipeType, - sta, - elapsed, - itemcond.Name, - itemcond.GotoId, isok)); - if (!IsEnd) - { - if ((!isok && condpipeType == HandlerType.Condition) || (isok && condpipeType == HandlerType.ConditionGoto)) - { - if (!string.IsNullOrEmpty(itemcond.GotoId)) - { - _prevPipe = _currentPipe; - _currentPipe = _aliasToId[itemcond.GotoId]; - _currentPipeIndex = _sequencePipes.IndexOf(_currentPipe); - return; - } - _currentPipeIndex++; - if (_currentPipeIndex < _sequencePipes.Count) - { - _prevPipe = _currentPipe; - _currentPipe = _sequencePipes[_currentPipeIndex]; - } - else - { - _finished = true; - } - return; - } - } - } - if (isok) - { - break; - } - } - } - - private void EnsureResultEventPipe(string idpipe, EventPipe eventPipe) - { - if (eventPipe.FinishedPipeAndFilter) - { - _finished = true; - } - var alias = _idToAlias[idpipe]; - if (eventPipe.ToRemove) - { - var index = _savedvalues.FindIndex(x => x.Id == idpipe); - if (index >= 0) - { - _savedvalues.RemoveAt(index); - } - } - else if (eventPipe.IsSaved) - { - var index = _savedvalues.FindIndex(x => x.Id == idpipe); - if (index >= 0) - { - _savedvalues[index] = (alias, idpipe, eventPipe.ValueToSave); - } - else - { - _savedvalues.Add((alias, idpipe, eventPipe.ValueToSave)); - } - } - } - private void EnsureResultEventPipeTask(string idtask, string? name, EventPipe eventPipe) { lock (_lockObj) @@ -800,5 +566,7 @@ private void EnsureResultEventPipeTask(string idtask, string? name, EventPipe } } } + + } } diff --git a/Src/Control/internal/PipeAndFilterService.cs b/Src/Control/internal/PipeAndFilterService.cs new file mode 100644 index 0000000..1ce638f --- /dev/null +++ b/Src/Control/internal/PipeAndFilterService.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PipeFilterCore.CommandsInterface; + +namespace PipeFilterCore.Control +{ + internal class PipeAndFilterService : IPipeAndFilterOptions, IPipeAndFilterServiceBuild where T : class + { + private readonly string? _serviceid; + readonly PipeAndFilterBuild _parameters; + + public PipeAndFilterService(string? serviceid, PipeAndFilterBuild parameters) + { + _serviceid = serviceid; + _parameters = parameters; + } + + public string? ServiceId => _serviceid; + + public Dictionary AliasToId => _parameters._aliasToId; + + public Dictionary IdToAlias => _parameters._idToAlias; + + public Dictionary MaxDegreeProcess => _parameters._maxDegreeProcess; + + public Dictionary, CancellationToken, + Task> pipehandle, + bool aggregateTasks, + List> precondhandle, + List status, + List<(string Id, Func, CancellationToken, Task> TaskHandle, PipeCondition? TaskCondition, string? NameTask, string? NameCondition)> tasks)> + Pipes => _parameters._pipes; + + IPipeAndFilterRunService IPipeAndFilterServiceBuild.Create() + { + return new PipeAndFilterControl(this); + } + } +} diff --git a/Src/Control/PipeCondition.cs b/Src/Control/internal/PipeCondition.cs similarity index 100% rename from Src/Control/PipeCondition.cs rename to Src/Control/internal/PipeCondition.cs diff --git a/Src/NugetREADME.md b/Src/NugetREADME.md index 26ee735..89e32d2 100644 --- a/Src/NugetREADME.md +++ b/Src/NugetREADME.md @@ -8,125 +8,86 @@ - First Release -## **PipeAndFilter - Sample Usage** -```csharp -public class MyClass -{ - public int MyProperty { get; set; } -} -``` +## Usage +[**Top**](#table-of-contents) -```csharp -var contract = new MyClass { MyProperty = 10 }; +The **PipeAndFilter** use **fluent interface**; an object-oriented API whose design relies extensively on method chaining. Its goal is to increase code legibility. The term was coined in 2005 by Eric Evans and Martin Fowler. -var result = await PipeAndFilter - .Create() - .Init(contract) - .MaxDegreeProcess(4) - .CorrelationId(null) - .Logger(null) +### Sample-Console Usage + +```csharp +var result = await PipeAndFilter.New() .AddPipe(ExecPipe1) - .AddPipe(ExecPipe2) .WithCondition(CondFalse, "LastPipe") .WithCondition(CondTrue, null) .WithCondition(CondTrue, null) - .AddPipeTasks(AgregateTask) + .AddPipe(ExecPipe2) + .AddPipe(ExecPipe3) + .AddPipeTasks(AgregateTask) .WithCondition(CondTrue, null) - .AddTask(Task50) - .AddTaskCondition(Task100, CondFalse) - .AddTask(Task150) - .AddPipe(ExecPipe, "LastPipe") - .Run(); - -Console.WriteLine($"Contract value : {contract.MyProperty}"); -foreach (var item in pl.Status) -{ - Console.WriteLine($"{item.Alias ?? item.Id}:{item.Status.Value} => {item.Status.Elapsedtime}"); - foreach (var det in item.StatusDetails) - { - Console.WriteLine($"\t{det.TypeExec}:{det.GotoAlias ?? det.Alias}:{det.Condition} => :{det.Value}:{det.Elapsedtime}"); - } -} + .MaxDegreeProcess(4) + .AddTask(Task1) + .AddTaskCondition(Task2, CondFalse) + .AddTask(Task3) + .AddPipe(ExecPipe5, "LastPipe") + .BuildAndCreate() + .Init(contract) + .CorrelationId(null) + .Logger(null) + .Run(); ``` +### Sample-api/webUsage +[**Top**](#table-of-contents) + ```csharp -private static async Task Task50(EventPipe pipe, CancellationToken token) -{ - pipe.ChangeContract((contract) => - { - contract.MyProperty++; - }); - try - { - await Task.Delay(50, token); - pipe.SaveValue(50); - } - catch (TaskCanceledException) - { - //none - } -} -private static async Task Task100(EventPipe pipe, CancellationToken token) -{ - pipe.ChangeContract((contract) => - { - contract.MyProperty++; - }); - try - { - await Task.Delay(100, token); - pipe.SaveValue(100); - } - catch (TaskCanceledException) - { - //none - } -} -private static async Task Task150(EventPipe pipe, CancellationToken token) +builder.Services + .AddPipeAndFilter( + PipeAndFilter.New() + .AddPipe(ExecPipe) + .Build()); + +``` + +```csharp +private static Task ExecPipe(EventPipe pipe, CancellationToken token) { pipe.ChangeContract((contract) => { - contract.MyProperty++; + contract.TemperatureC += 10; }); - try - { - await Task.Delay(150, token); - pipe.SaveValue(150); - } - catch (TaskCanceledException) - { - //none - } -} -private static Task ExecPipe(EventPipe pipe, CancellationToken token) -{ - pipe.SaveValue("Saved"); - return Task.CompletedTask; -} -private static Task AgregateTask(EventPipe pipe, CancellationToken token) -{ return Task.CompletedTask; } -private static async Task ExecPipe100(EventPipe pipe, CancellationToken token) +``` + +```csharp +[ApiController] +[Route("[controller]")] +public class WeatherForecastController : ControllerBase { - pipe.SaveValue("Saved0"); - try + private readonly ILogger _logger; + private readonly IPipeAndFilterServiceBuild _mypipe; + + public WeatherForecastController(ILogger logger, IPipeAndFilterServiceBuild pipeAndFilter) { - await Task.Delay(100, token); + _logger = logger; + _mypipes = pipeAndFilter; } - catch (TaskCanceledException) + + [HttpGet(Name = "GetWeatherForecast")] + public async Task Get(CancellationToken cancellation) { - //none + var cid = Guid.NewGuid().ToString(); + + var pipe = await _mypipes.First(x => x.ServiceId == "opc1") + .Create() + .Logger(_logger) + .CorrelationId(cid) + .Init(new WeatherForecast { Date = DateOnly.FromDateTime(DateTime.Now), Summary = "PipeAndFilter-Opc1", TemperatureC = 0 }) + .Run(cancellation); + return pipe.Result.Value! } } -private static async ValueTask CondFalse(EventPipe pipe, CancellationToken token) -{ - return await Task.FromResult(false); -} -private static ValueTask CondTrue(EventPipe pipe, CancellationToken token) -{ - ValueTask.FromResult(true); -} ``` ## Credits diff --git a/Src/PIpeAndFIlterExtensions.cs b/Src/PIpeAndFIlterExtensions.cs new file mode 100644 index 0000000..c479379 --- /dev/null +++ b/Src/PIpeAndFIlterExtensions.cs @@ -0,0 +1,27 @@ +// ******************************************************************************************** +// MIT LICENCE +// The maintenance and evolution is maintained by the PipeAndFilter project under MIT license +// ******************************************************************************************** + +using Microsoft.Extensions.DependencyInjection; + +namespace PipeFilterCore +{ + /// + /// Represents the extensions to add PipeAndFilter to the ServiceCollection. + /// + public static class PipeAndFilterExtensions + { + /// + /// Add PipeAndFilter to ServiceCollection. + /// + /// Type of contract. + /// The . + /// The PipeAndFilter + /// + public static IServiceCollection AddPipeAndFilter(this IServiceCollection services, IPipeAndFilterServiceBuild pipeAndFilterServiceBuild) where T : class + { + return services.AddSingleton(pipeAndFilterServiceBuild); + } + } +} diff --git a/Src/PipeAndFilter.csproj b/Src/PipeAndFilter.csproj index 818623c..7f03cac 100644 --- a/Src/PipeAndFilter.csproj +++ b/Src/PipeAndFilter.csproj @@ -45,6 +45,7 @@ + diff --git a/Src/README.txt b/Src/README.txt index 8b7b99c..7ea4aef 100644 --- a/Src/README.txt +++ b/Src/README.txt @@ -41,126 +41,82 @@ PipeAndFilter was developed in C# with target frameworks: - First Release -**PipeAndFilter Controls - Sample Usage** ------------------------------------------ - -public class MyClass -{ - public int MyProperty { get; set; } -} - -... - -var contract = new MyClass { MyProperty = 10 }; - -var result = await PipeAndFilter - .Create() - .Init(contract) - .MaxDegreeProcess(4) - .CorrelationId(null) - .Logger(null) +**PipeAndFilter Sample-console Usage** +-------------------------------------- +var result = await PipeAndFilter.New() .AddPipe(ExecPipe1) - .AddPipe(ExecPipe2) .WithCondition(CondFalse, "LastPipe") .WithCondition(CondTrue, null) .WithCondition(CondTrue, null) - .AddPipeTasks(AgregateTask) + .AddPipe(ExecPipe2) + .AddPipe(ExecPipe3) + .AddPipeTasks(AgregateTask) .WithCondition(CondTrue, null) - .AddTask(Task50) - .AddTaskCondition(Task100, CondFalse) - .AddTask(Task150) - .AddPipe(ExecPipe, "LastPipe") - .Run(); - -Console.WriteLine($"Contract value : {contract.MyProperty}"); -foreach (var item in pl.Status) -{ - Console.WriteLine($"{item.Alias ?? item.Id}:{item.Status.Value} => {item.Status.Elapsedtime}"); - foreach (var det in item.StatusDetails) - { - Console.WriteLine($"\t{det.TypeExec}:{det.GotoAlias ?? det.Alias}:{det.Condition} => :{det.Value}:{det.Elapsedtime}"); - } -} + .MaxDegreeProcess(4) + .AddTask(Task1) + .AddTaskCondition(Task2, CondFalse) + .AddTask(Task3) + .AddPipe(ExecPipe5, "LastPipe") + .BuildAndCreate() + .Init(contract) + .CorrelationId(null) + .Logger(null) + .Run(); +**PipeAndFilter Sample-api/web Usage** +-------------------------------------- + +Program.cs +---------- + +builder.Services + .AddPipeAndFilter( + PipeAndFilter.New() + .AddPipe(ExecPipe) + .Build()); +... ... -private static async Task Task50(EventPipe pipe, CancellationToken token) -{ - pipe.ChangeContract((contract) => - { - contract.MyProperty++; - }); - try - { - await Task.Delay(50, token); - pipe.SaveValue(50); - } - catch (TaskCanceledException) - { - //none - } -} -private static async Task Task100(EventPipe pipe, CancellationToken token) +private static Task ExecPipe(EventPipe pipe, CancellationToken token) { pipe.ChangeContract((contract) => { - contract.MyProperty++; + contract.TemperatureC += 10; }); - try - { - await Task.Delay(100, token); - pipe.SaveValue(100); - } - catch (TaskCanceledException) - { - //none - } -} -private static async Task Task150(EventPipe pipe, CancellationToken token) -{ - pipe.ChangeContract((contract) => - { - contract.MyProperty++; - }); - try - { - await Task.Delay(150, token); - pipe.SaveValue(150); - } - catch (TaskCanceledException) - { - //none - } -} -private static Task ExecPipe(EventPipe pipe, CancellationToken token) -{ - pipe.SaveValue("Saved"); return Task.CompletedTask; } -private static Task AgregateTask(EventPipe pipe, CancellationToken token) -{ - return Task.CompletedTask; -} -private static async Task ExecPipe100(EventPipe pipe, CancellationToken token) + + +WeatherForecastController.cs +---------------------------- + +[ApiController] +[Route("[controller]")] +public class WeatherForecastController : ControllerBase { - pipe.SaveValue("Saved0"); - try + private readonly ILogger _logger; + private readonly IPipeAndFilterServiceBuild _mypipe; + + public WeatherForecastController(ILogger logger, IPipeAndFilterServiceBuild pipeAndFilter) { - await Task.Delay(100, token); + _logger = logger; + _mypipes = pipeAndFilter; } - catch (TaskCanceledException) + + [HttpGet(Name = "GetWeatherForecast")] + public async Task Get(CancellationToken cancellation) { - //none + var cid = Guid.NewGuid().ToString(); + + var pipe = await _mypipes.First(x => x.ServiceId == "opc1") + .Create() + .Logger(_logger) + .CorrelationId(cid) + .Init(new WeatherForecast { Date = DateOnly.FromDateTime(DateTime.Now), Summary = "PipeAndFilter-Opc1", TemperatureC = 0 }) + .Run(cancellation); + return pipe.Result.Value! } } -private static async ValueTask CondFalse(EventPipe pipe, CancellationToken token) -{ - return await Task.FromResult(false); -} -private static ValueTask CondTrue(EventPipe pipe, CancellationToken token) -{ - ValueTask.FromResult(true); -} **License** ----------- diff --git a/docs/apis/apis.md b/docs/apis/apis.md index fbf51e5..e26a094 100644 --- a/docs/apis/apis.md +++ b/docs/apis/apis.md @@ -15,18 +15,28 @@ - [HandlerType](./pipefiltercore.handlertype.md) -- [IPipeAndFilter<T>](./pipefiltercore.ipipeandfilter-1.md) +- [IPipeAndFilterBuild<T>](./pipefiltercore.ipipeandfilterbuild-1.md) -- [IPipeAndFilterConditions<T>](./pipefiltercore.ipipeandfilterconditions-1.md) +- [IPipeAndFilterConditionsService<T>](./pipefiltercore.ipipeandfilterconditionsservice-1.md) -- [IPipeAndFilterInit<T>](./pipefiltercore.ipipeandfilterinit-1.md) +- [IPipeAndFilterCreateService<T>](./pipefiltercore.ipipeandfiltercreateservice-1.md) -- [IPipeAndFilterTasks<T>](./pipefiltercore.ipipeandfiltertasks-1.md) +- [IPipeAndFilterRun<T>](./pipefiltercore.ipipeandfilterrun-1.md) + +- [IPipeAndFilterRunService<T>](./pipefiltercore.ipipeandfilterrunservice-1.md) + +- [IPipeAndFilterService<T>](./pipefiltercore.ipipeandfilterservice-1.md) + +- [IPipeAndFilterServiceBuild<T>](./pipefiltercore.ipipeandfilterservicebuild-1.md) + +- [IPipeAndFilterTasksService<T>](./pipefiltercore.ipipeandfiltertasksservice-1.md) - [PipeAndFilter](./pipefiltercore.pipeandfilter.md) - [PipeAndFilterException](./pipefiltercore.pipeandfilterexception.md) +- [PipeAndFilterExtensions](./pipefiltercore.pipeandfilterextensions.md) + - [PipeRanStatus](./pipefiltercore.piperanstatus.md) - [PipeStatus](./pipefiltercore.pipestatus.md) diff --git a/docs/apis/pipefiltercore.eventpipe-1.md b/docs/apis/pipefiltercore.eventpipe-1.md index 93d26e1..99fc7f6 100644 --- a/docs/apis/pipefiltercore.eventpipe-1.md +++ b/docs/apis/pipefiltercore.eventpipe-1.md @@ -28,7 +28,7 @@ Inheritance [Object](https://docs.microsoft.com/en-us/dotnet/api/system.object) ### **CorrelationId** -The Correlation Id +The Correlation Id. ```csharp public string CorrelationId { get; } @@ -64,7 +64,7 @@ public string FromAlias { get; } ### **Logger** -The log handler +The log handler. ```csharp public ILogger Logger { get; } @@ -76,7 +76,7 @@ ILogger
###
**SavedPipes** -The values saved ​​associated with pipes +The values saved ​​associated with pipes. ```csharp public ImmutableArray> SavedPipes { get; } @@ -165,7 +165,6 @@ The action to change value. **Remarks:** The action will only be executed if the contract exists. -
See . ###
**EndPipeAndFilter()** @@ -177,7 +176,7 @@ public void EndPipeAndFilter() ### **RemoveSavedValue()** -Remove a value associated with this pipe or task . +Remove a value associated with this pipe or task. ```csharp public void RemoveSavedValue() diff --git a/docs/apis/pipefiltercore.ipipeandfilterbuild-1.md b/docs/apis/pipefiltercore.ipipeandfilterbuild-1.md new file mode 100644 index 0000000..aa0f96f --- /dev/null +++ b/docs/apis/pipefiltercore.ipipeandfilterbuild-1.md @@ -0,0 +1,58 @@ +# PipeAndFilter API:IPipeAndFilterBuild + +[![Build](https://github.com/FRACerqueira/PipeAndFilter/workflows/Build/badge.svg)](https://github.com/FRACerqueira/PipeAndFilter/actions/workflows/build.yml) +[![License](https://img.shields.io/badge/License-MIT-brightgreen.svg)](https://github.com/FRACerqueira/PipeAndFilter/blob/master/LICENSE) +[![NuGet](https://img.shields.io/nuget/v/PipeAndFilter)](https://www.nuget.org/packages/PipeAndFilter/) +[![Downloads](https://img.shields.io/nuget/dt/PipeAndFilter)](https://www.nuget.org/packages/PipeAndFilter/) + +[**Back to List Api**](./apis.md) + +# IPipeAndFilterBuild<T> + +Namespace: PipeFilterCore + +Represents the commands for build a service and Create the instance to run. + +```csharp +public interface IPipeAndFilterBuild +``` + +#### Type Parameters + +`T`
+Type of contract. + +## Methods + +###
**Build(String)** + +Build PipeAndFilter to add into ServiceCollection. + +```csharp +IPipeAndFilterServiceBuild Build(string serviceId) +``` + +#### Parameters + +`serviceId` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
+The service Id. + +#### Returns + +[IPipeAndFilterServiceBuild<T>](./pipefiltercore.ipipeandfilterservicebuild-1.md) + +###
**BuildAndCreate()** + +Build and create PipeAndFilter to run. + +```csharp +IPipeAndFilterRunService BuildAndCreate() +``` + +#### Returns + +[IPipeAndFilterRunService<T>](./pipefiltercore.ipipeandfilterrunservice-1.md) + + +- - - +[**Back to List Api**](./apis.md) diff --git a/docs/apis/pipefiltercore.ipipeandfilter-1.md b/docs/apis/pipefiltercore.ipipeandfilterconditionsservice-1.md similarity index 74% rename from docs/apis/pipefiltercore.ipipeandfilter-1.md rename to docs/apis/pipefiltercore.ipipeandfilterconditionsservice-1.md index 7e2bc47..07182af 100644 --- a/docs/apis/pipefiltercore.ipipeandfilter-1.md +++ b/docs/apis/pipefiltercore.ipipeandfilterconditionsservice-1.md @@ -1,4 +1,4 @@ -# PipeAndFilter API:IPipeAndFilter +# PipeAndFilter API:IPipeAndFilterConditionsService [![Build](https://github.com/FRACerqueira/PipeAndFilter/workflows/Build/badge.svg)](https://github.com/FRACerqueira/PipeAndFilter/actions/workflows/build.yml) [![License](https://img.shields.io/badge/License-MIT-brightgreen.svg)](https://github.com/FRACerqueira/PipeAndFilter/blob/master/LICENSE) @@ -7,14 +7,14 @@ [**Back to List Api**](./apis.md) -# IPipeAndFilter<T> +# IPipeAndFilterConditionsService<T> Namespace: PipeFilterCore -Represents the commands for pipe. +Represents commands for conditions. ```csharp -public interface IPipeAndFilter +public interface IPipeAndFilterConditionsService : IPipeAndFilterBuild ``` #### Type Parameters @@ -22,6 +22,8 @@ public interface IPipeAndFilter `T`
Type of contract. +Implements IPipeAndFilterBuild<T> + ## Methods ###
**AddPipe(Func<EventPipe<T>, CancellationToken, Task>, String)** @@ -29,7 +31,7 @@ Type of contract. Add new pipe. ```csharp -IPipeAndFilter AddPipe(Func, CancellationToken, Task> command, string alias) +IPipeAndFilterService AddPipe(Func, CancellationToken, Task> command, string alias) ``` #### Parameters @@ -43,7 +45,7 @@ The unique alias for pipe. #### Returns -[IPipeAndFilter<T>](./pipefiltercore.ipipeandfilter-1.md) +[IPipeAndFilterService<T>](./pipefiltercore.ipipeandfilterservice-1.md) **Remarks:** @@ -54,7 +56,7 @@ Alias ​​is used to reference in another pipe. Add new pipe aggregate tasks. ```csharp -IPipeAndFilterTasks AddPipeTasks(Func, CancellationToken, Task> command, string alias) +IPipeAndFilterTasksService AddPipeTasks(Func, CancellationToken, Task> command, string alias) ``` #### Parameters @@ -69,30 +71,18 @@ The unique alias for pipe. #### Returns -[IPipeAndFilterTasks<T>](./pipefiltercore.ipipeandfiltertasks-1.md) +[IPipeAndFilterTasksService<T>](./pipefiltercore.ipipeandfiltertasksservice-1.md) **Remarks:** Alias ​​is used to reference in another pipe. -### **Run()** - -Execute PipeAndFilter. - -```csharp -ValueTask> Run() -``` - -#### Returns - -[ResultPipeAndFilter<T>](./pipefiltercore.resultpipeandfilter-1.md) - ### **WithCondition(Func<EventPipe<T>, CancellationToken, ValueTask<Boolean>>, String, String)** Add new condition. ```csharp -IPipeAndFilterConditions WithCondition(Func, CancellationToken, ValueTask> condition, string aliasgoto, string namecondition) +IPipeAndFilterConditionsService WithCondition(Func, CancellationToken, ValueTask> condition, string aliasgoto, string namecondition) ``` #### Parameters @@ -109,7 +99,7 @@ The name for condition(optional). #### Returns -[IPipeAndFilterConditions<T>](./pipefiltercore.ipipeandfilterconditions-1.md) +[IPipeAndFilterConditionsService<T>](./pipefiltercore.ipipeandfilterconditionsservice-1.md) - - - diff --git a/docs/apis/pipefiltercore.ipipeandfilterinit-1.md b/docs/apis/pipefiltercore.ipipeandfiltercreateservice-1.md similarity index 51% rename from docs/apis/pipefiltercore.ipipeandfilterinit-1.md rename to docs/apis/pipefiltercore.ipipeandfiltercreateservice-1.md index 04187f0..7a877d6 100644 --- a/docs/apis/pipefiltercore.ipipeandfilterinit-1.md +++ b/docs/apis/pipefiltercore.ipipeandfiltercreateservice-1.md @@ -1,4 +1,4 @@ -# PipeAndFilter API:IPipeAndFilterInit +# PipeAndFilter API:IPipeAndFilterCreateService [![Build](https://github.com/FRACerqueira/PipeAndFilter/workflows/Build/badge.svg)](https://github.com/FRACerqueira/PipeAndFilter/actions/workflows/build.yml) [![License](https://img.shields.io/badge/License-MIT-brightgreen.svg)](https://github.com/FRACerqueira/PipeAndFilter/blob/master/LICENSE) @@ -7,20 +7,22 @@ [**Back to List Api**](./apis.md) -# IPipeAndFilterInit<T> +# IPipeAndFilterCreateService<T> Namespace: PipeFilterCore -Represents command for initialization +Represents the commands for Pipes. ```csharp -public interface IPipeAndFilterInit +public interface IPipeAndFilterCreateService : IPipeAndFilterBuild ``` #### Type Parameters `T`
-Type of contract +Type of contract. + +Implements IPipeAndFilterBuild<T> ## Methods @@ -29,7 +31,7 @@ Type of contract Add new pipe. ```csharp -IPipeAndFilter AddPipe(Func, CancellationToken, Task> command, string alias) +IPipeAndFilterService AddPipe(Func, CancellationToken, Task> command, string alias) ``` #### Parameters @@ -43,7 +45,7 @@ The unique alias for pipe. #### Returns -[IPipeAndFilter<T>](./pipefiltercore.ipipeandfilter-1.md) +[IPipeAndFilterService<T>](./pipefiltercore.ipipeandfilterservice-1.md) **Remarks:** @@ -54,7 +56,7 @@ Alias ​​is used to reference in another pipe. Add new pipe aggregate tasks. ```csharp -IPipeAndFilterTasks AddPipeTasks(Func, CancellationToken, Task> command, string alias) +IPipeAndFilterTasksService AddPipeTasks(Func, CancellationToken, Task> command, string alias) ``` #### Parameters @@ -69,84 +71,12 @@ The unique alias for pipe. #### Returns -[IPipeAndFilter<T>](./pipefiltercore.ipipeandfilter-1.md) +[IPipeAndFilterTasksService<T>](./pipefiltercore.ipipeandfiltertasksservice-1.md) **Remarks:** Alias ​​is used to reference in another pipe. -###
**CorrelationId(String)** - -The Correlation Id - -```csharp -IPipeAndFilterInit CorrelationId(string value) -``` - -#### Parameters - -`value` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
-Correlation Id value - -#### Returns - -[IPipeAndFilterInit<T>](./pipefiltercore.ipipeandfilterinit-1.md) - -###
**Init(T)** - -Initial contract value. - -```csharp -IPipeAndFilterInit Init(T contract) -``` - -#### Parameters - -`contract` T
-The contract. - -#### Returns - -[IPipeAndFilterInit<T>](./pipefiltercore.ipipeandfilterinit-1.md) - -###
**Logger(ILogger)** - -The logger handler - -```csharp -IPipeAndFilterInit Logger(ILogger value) -``` - -#### Parameters - -`value` ILogger
-logger handler value - -#### Returns - -[IPipeAndFilterInit<T>](./pipefiltercore.ipipeandfilterinit-1.md) - -###
**MaxDegreeProcess(Int32)** - -Maximum number of concurrent tasks enable. - -```csharp -IPipeAndFilterInit MaxDegreeProcess(int value) -``` - -#### Parameters - -`value` [Int32](https://docs.microsoft.com/en-us/dotnet/api/system.int32)
-Number of concurrent tasks. - -#### Returns - -[IPipeAndFilterInit<T>](./pipefiltercore.ipipeandfilterinit-1.md) - -**Remarks:** - -The default value is number of processors. - - - - [**Back to List Api**](./apis.md) diff --git a/docs/apis/pipefiltercore.ipipeandfilterrun-1.md b/docs/apis/pipefiltercore.ipipeandfilterrun-1.md new file mode 100644 index 0000000..9d07e32 --- /dev/null +++ b/docs/apis/pipefiltercore.ipipeandfilterrun-1.md @@ -0,0 +1,45 @@ +# PipeAndFilter API:IPipeAndFilterRun + +[![Build](https://github.com/FRACerqueira/PipeAndFilter/workflows/Build/badge.svg)](https://github.com/FRACerqueira/PipeAndFilter/actions/workflows/build.yml) +[![License](https://img.shields.io/badge/License-MIT-brightgreen.svg)](https://github.com/FRACerqueira/PipeAndFilter/blob/master/LICENSE) +[![NuGet](https://img.shields.io/nuget/v/PipeAndFilter)](https://www.nuget.org/packages/PipeAndFilter/) +[![Downloads](https://img.shields.io/nuget/dt/PipeAndFilter)](https://www.nuget.org/packages/PipeAndFilter/) + +[**Back to List Api**](./apis.md) + +# IPipeAndFilterRun<T> + +Namespace: PipeFilterCore + +Represents the command for Run. + +```csharp +public interface IPipeAndFilterRun +``` + +#### Type Parameters + +`T`
+Type of contract. + +## Methods + +###
**Run(Nullable<CancellationToken>)** + +Execute PipeAndFilter. + +```csharp +ValueTask> Run(Nullable cancellation) +``` + +#### Parameters + +`cancellation` [Nullable<CancellationToken>](https://docs.microsoft.com/en-us/dotnet/api/system.nullable-1)
+ +#### Returns + +[ResultPipeAndFilter<T>](./pipefiltercore.resultpipeandfilter-1.md) + + +- - - +[**Back to List Api**](./apis.md) diff --git a/docs/apis/pipefiltercore.ipipeandfilterrunservice-1.md b/docs/apis/pipefiltercore.ipipeandfilterrunservice-1.md new file mode 100644 index 0000000..2e19ff5 --- /dev/null +++ b/docs/apis/pipefiltercore.ipipeandfilterrunservice-1.md @@ -0,0 +1,96 @@ +# PipeAndFilter API:IPipeAndFilterRunService + +[![Build](https://github.com/FRACerqueira/PipeAndFilter/workflows/Build/badge.svg)](https://github.com/FRACerqueira/PipeAndFilter/actions/workflows/build.yml) +[![License](https://img.shields.io/badge/License-MIT-brightgreen.svg)](https://github.com/FRACerqueira/PipeAndFilter/blob/master/LICENSE) +[![NuGet](https://img.shields.io/nuget/v/PipeAndFilter)](https://www.nuget.org/packages/PipeAndFilter/) +[![Downloads](https://img.shields.io/nuget/dt/PipeAndFilter)](https://www.nuget.org/packages/PipeAndFilter/) + +[**Back to List Api**](./apis.md) + +# IPipeAndFilterRunService<T> + +Namespace: PipeFilterCore + +Represents commands for initialization and run. + +```csharp +public interface IPipeAndFilterRunService : IPipeAndFilterRun +``` + +#### Type Parameters + +`T`
+Type of contract. + +Implements IPipeAndFilterRun<T> + +## Properties + +###
**ServiceId** + +The service id for this type. + +```csharp +public abstract string ServiceId { get; } +``` + +#### Property Value + +[String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
+ +## Methods + +###
**CorrelationId(String)** + +The Correlation Id. + +```csharp +IPipeAndFilterRunService CorrelationId(string value) +``` + +#### Parameters + +`value` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
+Correlation Id value. + +#### Returns + +[IPipeAndFilterRunService<T>](./pipefiltercore.ipipeandfilterrunservice-1.md) + +###
**Init(T)** + +Initial contract value. + +```csharp +IPipeAndFilterRunService Init(T contract) +``` + +#### Parameters + +`contract` T
+The contract. + +#### Returns + +[IPipeAndFilterRunService<T>](./pipefiltercore.ipipeandfilterrunservice-1.md) + +###
**Logger(ILogger)** + +The logger handler. + +```csharp +IPipeAndFilterRunService Logger(ILogger value) +``` + +#### Parameters + +`value` ILogger
+logger handler value. + +#### Returns + +[IPipeAndFilterRunService<T>](./pipefiltercore.ipipeandfilterrunservice-1.md) + + +- - - +[**Back to List Api**](./apis.md) diff --git a/docs/apis/pipefiltercore.ipipeandfilterconditions-1.md b/docs/apis/pipefiltercore.ipipeandfilterservice-1.md similarity index 56% rename from docs/apis/pipefiltercore.ipipeandfilterconditions-1.md rename to docs/apis/pipefiltercore.ipipeandfilterservice-1.md index 0a3cfc4..40a24eb 100644 --- a/docs/apis/pipefiltercore.ipipeandfilterconditions-1.md +++ b/docs/apis/pipefiltercore.ipipeandfilterservice-1.md @@ -1,4 +1,4 @@ -# PipeAndFilter API:IPipeAndFilterConditions +# PipeAndFilter API:IPipeAndFilterService [![Build](https://github.com/FRACerqueira/PipeAndFilter/workflows/Build/badge.svg)](https://github.com/FRACerqueira/PipeAndFilter/actions/workflows/build.yml) [![License](https://img.shields.io/badge/License-MIT-brightgreen.svg)](https://github.com/FRACerqueira/PipeAndFilter/blob/master/LICENSE) @@ -7,20 +7,22 @@ [**Back to List Api**](./apis.md) -# IPipeAndFilterConditions<T> +# IPipeAndFilterService<T> Namespace: PipeFilterCore -Represents command for conditions +Represents the commands for pipes. ```csharp -public interface IPipeAndFilterConditions +public interface IPipeAndFilterService : IPipeAndFilterBuild ``` #### Type Parameters `T`
-Type of contract +Type of contract. + +Implements IPipeAndFilterBuild<T> ## Methods @@ -29,7 +31,7 @@ Type of contract Add new pipe. ```csharp -IPipeAndFilter AddPipe(Func, CancellationToken, Task> command, string alias) +IPipeAndFilterService AddPipe(Func, CancellationToken, Task> command, string alias) ``` #### Parameters @@ -43,30 +45,44 @@ The unique alias for pipe. #### Returns -[IPipeAndFilter<T>](./pipefiltercore.ipipeandfilter-1.md) +[IPipeAndFilterService<T>](./pipefiltercore.ipipeandfilterservice-1.md) **Remarks:** Alias ​​is used to reference in another pipe. -###
**Run()** +### **AddPipeTasks(Func<EventPipe<T>, CancellationToken, Task>, String)** -Execute the PipeAndFilter +Add new pipe aggregate tasks. ```csharp -ValueTask> Run() +IPipeAndFilterTasksService AddPipeTasks(Func, CancellationToken, Task> command, string alias) ``` +#### Parameters + +`command` Func<EventPipe<T>, CancellationToken, Task>
+The handler pipe aggregate to execute. +
The handler command will run after all tasks are executed. + +`alias` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
+The unique alias for pipe. +
If the alias is omitted, the alias will be the handler name followed by the reference quantity (if any). + #### Returns -[ResultPipeAndFilter<T>](./pipefiltercore.resultpipeandfilter-1.md) +[IPipeAndFilterTasksService<T>](./pipefiltercore.ipipeandfiltertasksservice-1.md) + +**Remarks:** + +Alias ​​is used to reference in another pipe. ###
**WithCondition(Func<EventPipe<T>, CancellationToken, ValueTask<Boolean>>, String, String)** Add new condition. ```csharp -IPipeAndFilterConditions WithCondition(Func, CancellationToken, ValueTask> condition, string aliasgoto, string namecondition) +IPipeAndFilterConditionsService WithCondition(Func, CancellationToken, ValueTask> condition, string aliasgoto, string namecondition) ``` #### Parameters @@ -83,7 +99,7 @@ The name for condition(optional). #### Returns -[IPipeAndFilterConditions<T>](./pipefiltercore.ipipeandfilterconditions-1.md) +[IPipeAndFilterConditionsService<T>](./pipefiltercore.ipipeandfilterconditionsservice-1.md) - - - diff --git a/docs/apis/pipefiltercore.ipipeandfilterservicebuild-1.md b/docs/apis/pipefiltercore.ipipeandfilterservicebuild-1.md new file mode 100644 index 0000000..9f01b2d --- /dev/null +++ b/docs/apis/pipefiltercore.ipipeandfilterservicebuild-1.md @@ -0,0 +1,55 @@ +# PipeAndFilter API:IPipeAndFilterServiceBuild + +[![Build](https://github.com/FRACerqueira/PipeAndFilter/workflows/Build/badge.svg)](https://github.com/FRACerqueira/PipeAndFilter/actions/workflows/build.yml) +[![License](https://img.shields.io/badge/License-MIT-brightgreen.svg)](https://github.com/FRACerqueira/PipeAndFilter/blob/master/LICENSE) +[![NuGet](https://img.shields.io/nuget/v/PipeAndFilter)](https://www.nuget.org/packages/PipeAndFilter/) +[![Downloads](https://img.shields.io/nuget/dt/PipeAndFilter)](https://www.nuget.org/packages/PipeAndFilter/) + +[**Back to List Api**](./apis.md) + +# IPipeAndFilterServiceBuild<T> + +Namespace: PipeFilterCore + +Represents the commands for create a instance. + +```csharp +public interface IPipeAndFilterServiceBuild +``` + +#### Type Parameters + +`T`
+Type of contract. + +## Properties + +###
**ServiceId** + +The service id for this type. + +```csharp +public abstract string ServiceId { get; } +``` + +#### Property Value + +[String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
+ +## Methods + +###
**Create()** + +Create a instance. + +```csharp +IPipeAndFilterRunService Create() +``` + +#### Returns + +[IPipeAndFilterRunService<T>](./pipefiltercore.ipipeandfilterrunservice-1.md) + + +- - - +[**Back to List Api**](./apis.md) diff --git a/docs/apis/pipefiltercore.ipipeandfiltertasks-1.md b/docs/apis/pipefiltercore.ipipeandfiltertasksservice-1.md similarity index 56% rename from docs/apis/pipefiltercore.ipipeandfiltertasks-1.md rename to docs/apis/pipefiltercore.ipipeandfiltertasksservice-1.md index 3c8535c..a17906b 100644 --- a/docs/apis/pipefiltercore.ipipeandfiltertasks-1.md +++ b/docs/apis/pipefiltercore.ipipeandfiltertasksservice-1.md @@ -1,4 +1,4 @@ -# PipeAndFilter API:IPipeAndFilterTasks +# PipeAndFilter API:IPipeAndFilterTasksService [![Build](https://github.com/FRACerqueira/PipeAndFilter/workflows/Build/badge.svg)](https://github.com/FRACerqueira/PipeAndFilter/actions/workflows/build.yml) [![License](https://img.shields.io/badge/License-MIT-brightgreen.svg)](https://github.com/FRACerqueira/PipeAndFilter/blob/master/LICENSE) @@ -7,20 +7,22 @@ [**Back to List Api**](./apis.md) -# IPipeAndFilterTasks<T> +# IPipeAndFilterTasksService<T> Namespace: PipeFilterCore -Represents commands for task +Represents commands for task. ```csharp -public interface IPipeAndFilterTasks +public interface IPipeAndFilterTasksService : IPipeAndFilterBuild ``` #### Type Parameters `T`
-Type of contract +Type of contract. + +Implements IPipeAndFilterBuild<T> ## Methods @@ -29,7 +31,7 @@ Type of contract Add new pipe. ```csharp -IPipeAndFilter AddPipe(Func, CancellationToken, Task> command, string alias) +IPipeAndFilterService AddPipe(Func, CancellationToken, Task> command, string alias) ``` #### Parameters @@ -43,7 +45,33 @@ The unique alias for pipe. #### Returns -[IPipeAndFilter<T>](./pipefiltercore.ipipeandfilter-1.md) +[IPipeAndFilterService<T>](./pipefiltercore.ipipeandfilterservice-1.md) + +**Remarks:** + +Alias ​​is used to reference in another pipe. + +###
**AddPipeTasks(Func<EventPipe<T>, CancellationToken, Task>, String)** + +Add new pipe aggregate tasks. + +```csharp +IPipeAndFilterTasksService AddPipeTasks(Func, CancellationToken, Task> command, string alias) +``` + +#### Parameters + +`command` Func<EventPipe<T>, CancellationToken, Task>
+The handler pipe aggregate to execute. +
The handler command will run after all tasks are executed. + +`alias` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
+The unique alias for pipe. +
If the alias is omitted, the alias will be the handler name followed by the reference quantity (if any). + +#### Returns + +[IPipeAndFilterTasksService<T>](./pipefiltercore.ipipeandfiltertasksservice-1.md) **Remarks:** @@ -54,7 +82,7 @@ Alias ​​is used to reference in another pipe. Add new task (execution in parallel) through pipe. ```csharp -IPipeAndFilterTasks AddTask(Func, CancellationToken, Task> command, string nametask) +IPipeAndFilterTasksService AddTask(Func, CancellationToken, Task> command, string nametask) ``` #### Parameters @@ -67,14 +95,14 @@ The name for task (optional). #### Returns -[IPipeAndFilterTasks<T>](./pipefiltercore.ipipeandfiltertasks-1.md) +[IPipeAndFilterTasksService<T>](./pipefiltercore.ipipeandfiltertasksservice-1.md) ###
**AddTaskCondition(Func<EventPipe<T>, CancellationToken, Task>, Func<EventPipe<T>, CancellationToken, ValueTask<Boolean>>, String, String)** Add new task (execution in parallel) through pipe with a condition. ```csharp -IPipeAndFilterTasks AddTaskCondition(Func, CancellationToken, Task> command, Func, CancellationToken, ValueTask> condition, string nametask, string namecondition) +IPipeAndFilterTasksService AddTaskCondition(Func, CancellationToken, Task> command, Func, CancellationToken, ValueTask> condition, string nametask, string namecondition) ``` #### Parameters @@ -93,26 +121,35 @@ The name for condition (optional). #### Returns -[IPipeAndFilterTasks<T>](./pipefiltercore.ipipeandfiltertasks-1.md) +[IPipeAndFilterTasksService<T>](./pipefiltercore.ipipeandfiltertasksservice-1.md) -### **Run()** +### **MaxDegreeProcess(Int32)** -Execute the PipeAndFilter +Maximum number of concurrent tasks enable. ```csharp -ValueTask> Run() +IPipeAndFilterTasksService MaxDegreeProcess(int value) ``` +#### Parameters + +`value` [Int32](https://docs.microsoft.com/en-us/dotnet/api/system.int32)
+Number of concurrent tasks. + #### Returns -[ResultPipeAndFilter<T>](./pipefiltercore.resultpipeandfilter-1.md) +[IPipeAndFilterTasksService<T>](./pipefiltercore.ipipeandfiltertasksservice-1.md) + +**Remarks:** + +The default value is number of processors. ###
**WithCondition(Func<EventPipe<T>, CancellationToken, ValueTask<Boolean>>, String, String)** Add new condition. ```csharp -IPipeAndFilterTasks WithCondition(Func, CancellationToken, ValueTask> condition, string aliasgoto, string namecondition) +IPipeAndFilterTasksService WithCondition(Func, CancellationToken, ValueTask> condition, string aliasgoto, string namecondition) ``` #### Parameters @@ -129,7 +166,7 @@ The name for condition(optional). #### Returns -[IPipeAndFilterTasks<T>](./pipefiltercore.ipipeandfiltertasks-1.md) +[IPipeAndFilterTasksService<T>](./pipefiltercore.ipipeandfiltertasksservice-1.md) - - - diff --git a/docs/apis/pipefiltercore.pipeandfilter.md b/docs/apis/pipefiltercore.pipeandfilter.md index ae11706..0adfeb1 100644 --- a/docs/apis/pipefiltercore.pipeandfilter.md +++ b/docs/apis/pipefiltercore.pipeandfilter.md @@ -11,7 +11,7 @@ Namespace: PipeFilterCore -Represents PipeAndFilter Extension. +Represents PipeAndFilter Creator. ```csharp public static class PipeAndFilter @@ -21,31 +21,21 @@ Inheritance [Object](https://docs.microsoft.com/en-us/dotnet/api/system.object) ## Methods -### **Create<T>(Nullable<CancellationToken>)** +### **New<T>()** -Create PipeAndFilter. +Create PipeAndFilter service. ```csharp -public static IPipeAndFilterInit Create(Nullable cts) +public static IPipeAndFilterCreateService New() ``` #### Type Parameters `T`
-Type of return. - -#### Parameters - -`cts` [Nullable<CancellationToken>](https://docs.microsoft.com/en-us/dotnet/api/system.nullable-1)
-The [CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken) #### Returns -[IPipeAndFilterInit<T>](./pipefiltercore.ipipeandfilterinit-1.md) - -**Remarks:** - -If [CancellationToken](https://docs.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken) ommited the value is 'CancellationToken.None'. +[IPipeAndFilterCreateService<T>](./pipefiltercore.ipipeandfiltercreateservice-1.md) - - - diff --git a/docs/apis/pipefiltercore.pipeandfilterexception.md b/docs/apis/pipefiltercore.pipeandfilterexception.md index 533db0b..ea9e640 100644 --- a/docs/apis/pipefiltercore.pipeandfilterexception.md +++ b/docs/apis/pipefiltercore.pipeandfilterexception.md @@ -11,7 +11,7 @@ Namespace: PipeFilterCore -Represents a exception for Pipeline control. +Represents a exception for PipeAndFilter. ```csharp public class PipeAndFilterException : System.Exception, System.Runtime.Serialization.ISerializable @@ -24,7 +24,7 @@ Implements [ISerializable](https://docs.microsoft.com/en-us/dotnet/api/system.ru ###
**StatusInit** -The default status for initialize +The default status for initialize. ```csharp public static PipeStatus StatusInit; @@ -128,7 +128,7 @@ public MethodBase TargetSite { get; } ### **PipeAndFilterException(PipeStatus, String)** -Create PipeAndFilter-Exception +Create PipeAndFilter-Exception. ```csharp public PipeAndFilterException(PipeStatus status, string message) @@ -137,14 +137,14 @@ public PipeAndFilterException(PipeStatus status, string message) #### Parameters `status` [PipeStatus](./pipefiltercore.pipestatus.md)
-The status of step (pipe, condition or task) +The status of step (pipe, condition or task). `message` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
The message that describes the error. ###
**PipeAndFilterException(PipeStatus, String, Exception)** -Create PipeAndFilter-Exception with innerException +Create PipeAndFilter-Exception with innerException. ```csharp public PipeAndFilterException(PipeStatus status, string message, Exception innerException) @@ -153,13 +153,13 @@ public PipeAndFilterException(PipeStatus status, string message, Exception inner #### Parameters `status` [PipeStatus](./pipefiltercore.pipestatus.md)
-The status of step (pipe, condition or task) +The status of step (pipe, condition or task). `message` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
The message that describes the error. `innerException` [Exception](https://docs.microsoft.com/en-us/dotnet/api/system.exception)
-The exception that is the cause of the current exception, or a null reference +The exception that is the cause of the current exception, or a null reference. - - - diff --git a/docs/apis/pipefiltercore.pipeandfilterextensions.md b/docs/apis/pipefiltercore.pipeandfilterextensions.md new file mode 100644 index 0000000..ea4145d --- /dev/null +++ b/docs/apis/pipefiltercore.pipeandfilterextensions.md @@ -0,0 +1,51 @@ +# PipeAndFilter API:PipeAndFilterExtensions + +[![Build](https://github.com/FRACerqueira/PipeAndFilter/workflows/Build/badge.svg)](https://github.com/FRACerqueira/PipeAndFilter/actions/workflows/build.yml) +[![License](https://img.shields.io/badge/License-MIT-brightgreen.svg)](https://github.com/FRACerqueira/PipeAndFilter/blob/master/LICENSE) +[![NuGet](https://img.shields.io/nuget/v/PipeAndFilter)](https://www.nuget.org/packages/PipeAndFilter/) +[![Downloads](https://img.shields.io/nuget/dt/PipeAndFilter)](https://www.nuget.org/packages/PipeAndFilter/) + +[**Back to List Api**](./apis.md) + +# PipeAndFilterExtensions + +Namespace: PipeFilterCore + +Represents the extensions to add PipeAndFilter to the ServiceCollection. + +```csharp +public static class PipeAndFilterExtensions +``` + +Inheritance [Object](https://docs.microsoft.com/en-us/dotnet/api/system.object) → [PipeAndFilterExtensions](./pipefiltercore.pipeandfilterextensions.md) + +## Methods + +###
**AddPipeAndFilter<T>(IServiceCollection, IPipeAndFilterServiceBuild<T>)** + +Add PipeAndFilter to ServiceCollection. + +```csharp +public static IServiceCollection AddPipeAndFilter(IServiceCollection services, IPipeAndFilterServiceBuild pipeAndFilterServiceBuild) +``` + +#### Type Parameters + +`T`
+Type of contract. + +#### Parameters + +`services` IServiceCollection
+The . + +`pipeAndFilterServiceBuild` IPipeAndFilterServiceBuild<T>
+The PipeAndFilter + +#### Returns + + + + +- - - +[**Back to List Api**](./apis.md) diff --git a/docs/apis/pipefiltercore.piperanstatus.md b/docs/apis/pipefiltercore.piperanstatus.md index 000a7b2..a2e375b 100644 --- a/docs/apis/pipefiltercore.piperanstatus.md +++ b/docs/apis/pipefiltercore.piperanstatus.md @@ -99,13 +99,13 @@ PipeRanStatus(string id, string alias, IEnumerable details) #### Parameters `id` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
-The pipe Id +The pipe Id. `alias` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
-The pipe alias +The pipe alias. `details` [IEnumerable<PipeStatus>](https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1)
-The detailed status of all runs +The detailed status of all runs. - - - diff --git a/docs/apis/pipefiltercore.resultpipeandfilter-1.md b/docs/apis/pipefiltercore.resultpipeandfilter-1.md index 0653796..0a24b25 100644 --- a/docs/apis/pipefiltercore.resultpipeandfilter-1.md +++ b/docs/apis/pipefiltercore.resultpipeandfilter-1.md @@ -11,7 +11,7 @@ Namespace: PipeFilterCore -Represents the result of PipeAndFilter +Represents the result of PipeAndFilter. ```csharp public struct ResultPipeAndFilter @@ -51,7 +51,7 @@ public PipeAndFilterException Exception { get; } ###
**Status** -The status details of all pipes +The status details of all pipes. ```csharp public ImmutableArray Status { get; } @@ -63,7 +63,7 @@ ImmutableArray<PipeRanStatus>
###
**Value** -The Contract value +The Contract value. ```csharp public T Value { get; } @@ -77,7 +77,7 @@ T
###
**ResultPipeAndFilter()** -Create Result of PipeAndFilter +Create Result of PipeAndFilter. ```csharp ResultPipeAndFilter() @@ -86,7 +86,7 @@ ResultPipeAndFilter() #### Exceptions [PipeAndFilterException](./pipefiltercore.pipeandfilterexception.md)
-Message error +Message error. **Remarks:** diff --git a/docs/index.md b/docs/index.md index ec08eb1..404ed99 100644 --- a/docs/index.md +++ b/docs/index.md @@ -10,7 +10,6 @@ and the ability to parallel execute tasks over a pipe. .** **PipeAndFilter** was developed in C# with the **netstandard2.1**, **.NET 6** and **.NET 7** target frameworks. -**[Visit the official page for more documentation of PipeAndFilter](https://fracerqueira.github.io/PipeAndFilter)** ## Table of Contents @@ -71,125 +70,83 @@ dotnet run --project [name of sample] ## Usage [**Top**](#table-of-contents) -The controls use **fluent interface**; an object-oriented API whose design relies extensively on method chaining. Its goal is to increase code legibility. The term was coined in 2005 by Eric Evans and Martin Fowler. -```csharp -public class MyClass -{ - public int MyProperty { get; set; } -} -``` +The **PipeAndFilter** use **fluent interface**; an object-oriented API whose design relies extensively on method chaining. Its goal is to increase code legibility. The term was coined in 2005 by Eric Evans and Martin Fowler. -```csharp -var contract = new MyClass { MyProperty = 10 }; +### Sample-Console Usage -var result = await PipeAndFilter - .Create() - .Init(contract) - .MaxDegreeProcess(4) - .CorrelationId(null) - .Logger(null) +```csharp +var result = await PipeAndFilter.New() .AddPipe(ExecPipe1) - .AddPipe(ExecPipe2) .WithCondition(CondFalse, "LastPipe") .WithCondition(CondTrue, null) .WithCondition(CondTrue, null) - .AddPipeTasks(AgregateTask) + .AddPipe(ExecPipe2) + .AddPipe(ExecPipe3) + .AddPipeTasks(AgregateTask) .WithCondition(CondTrue, null) - .AddTask(Task50) - .AddTaskCondition(Task100, CondFalse) - .AddTask(Task150) - .AddPipe(ExecPipe, "LastPipe") - .Run(); - -Console.WriteLine($"Contract value : {contract.MyProperty}"); -foreach (var item in pl.Status) -{ - Console.WriteLine($"{item.Alias}:{item.Status.Value} => {item.Status.Elapsedtime}"); - foreach (var det in item.StatusDetails) - { - Console.WriteLine($"\t{det.TypeExec}:{det.GotoAlias ?? det.Alias}:{det.Condition} => :{det.Value}:{det.Elapsedtime}"); - } -} + .MaxDegreeProcess(4) + .AddTask(Task1) + .AddTaskCondition(Task2, CondFalse) + .AddTask(Task3) + .AddPipe(ExecPipe5, "LastPipe") + .BuildAndCreate() + .Init(contract) + .CorrelationId(null) + .Logger(null) + .Run(); ``` +### Sample-api/webUsage +[**Top**](#table-of-contents) + ```csharp -private static async Task Task50(EventPipe pipe, CancellationToken token) -{ - pipe.ChangeContract((contract) => - { - contract.MyProperty++; - }); - try - { - await Task.Delay(50, token); - pipe.SaveValue(50); - } - catch (TaskCanceledException) - { - //none - } -} -private static async Task Task100(EventPipe pipe, CancellationToken token) -{ - pipe.ChangeContract((contract) => - { - contract.MyProperty++; - }); - try - { - await Task.Delay(100, token); - pipe.SaveValue(100); - } - catch (TaskCanceledException) - { - //none - } -} -private static async Task Task150(EventPipe pipe, CancellationToken token) +builder.Services + .AddPipeAndFilter( + PipeAndFilter.New() + .AddPipe(ExecPipe) + .Build()); + +``` + +```csharp +private static Task ExecPipe(EventPipe pipe, CancellationToken token) { pipe.ChangeContract((contract) => { - contract.MyProperty++; + contract.TemperatureC += 10; }); - try - { - await Task.Delay(150, token); - pipe.SaveValue(150); - } - catch (TaskCanceledException) - { - //none - } -} -private static Task ExecPipe(EventPipe pipe, CancellationToken token) -{ - pipe.SaveValue("Saved"); - return Task.CompletedTask; -} -private static Task AgregateTask(EventPipe pipe, CancellationToken token) -{ return Task.CompletedTask; } -private static async Task ExecPipe100(EventPipe pipe, CancellationToken token) +``` + +```csharp +[ApiController] +[Route("[controller]")] +public class WeatherForecastController : ControllerBase { - pipe.SaveValue("Saved0"); - try + private readonly ILogger _logger; + private readonly IPipeAndFilterServiceBuild _mypipe; + + public WeatherForecastController(ILogger logger, IPipeAndFilterServiceBuild pipeAndFilter) { - await Task.Delay(100, token); + _logger = logger; + _mypipes = pipeAndFilter; } - catch (TaskCanceledException) + + [HttpGet(Name = "GetWeatherForecast")] + public async Task Get(CancellationToken cancellation) { - //none + var cid = Guid.NewGuid().ToString(); + + var pipe = await _mypipes.First(x => x.ServiceId == "opc1") + .Create() + .Logger(_logger) + .CorrelationId(cid) + .Init(new WeatherForecast { Date = DateOnly.FromDateTime(DateTime.Now), Summary = "PipeAndFilter-Opc1", TemperatureC = 0 }) + .Run(cancellation); + return pipe.Result.Value! } } -private static async ValueTask CondFalse(EventPipe pipe, CancellationToken token) -{ - return await Task.FromResult(false); -} -private static ValueTask CondTrue(EventPipe pipe, CancellationToken token) -{ - ValueTask.FromResult(true); -} ``` ## Code of Conduct