SimpleChain 8.0.5
See the version list below for details.
dotnet add package SimpleChain --version 8.0.5
NuGet\Install-Package SimpleChain -Version 8.0.5
<PackageReference Include="SimpleChain" Version="8.0.5" />
paket add SimpleChain --version 8.0.5
#r "nuget: SimpleChain, 8.0.5"
// Install SimpleChain as a Cake Addin #addin nuget:?package=SimpleChain&version=8.0.5 // Install SimpleChain as a Cake Tool #tool nuget:?package=SimpleChain&version=8.0.5
SimpleChain
A set of extensions to implement in a simple way the Chain-of-responsibility pattern for all types of objects.
Stack used
- .NET 8
- xUnit
- No dependencies
Installation
Depending on your usage, follow one of the guidelines below.
ASP.NET Core
Install with NuGet:
Install-Package SimpleChain
or with .NET CLI:
dotnet add package SimpleChain
How to Use
You can easily create a Chain
from every object
, Task
, IEnumerable
or IAsyncEnumerable
. All those examples are listened in the project tests:
Consider the example class Sale
internal class Sale
{
public string? SaleName { get; set; }
public Product[] Products { get; set; } = Array.Empty<Product>();
public double Total { get; set; }
public double Tax { get; set; }
}
internal sealed class Product
{
public required string Name { get; set; }
public required double Price { get; set; }
}
You can start a Chain
directly like this:
object
var sale = new Sale();
var chain = sale.ToChain()
.AddNode(sale =>
{
sale.SaleName = "Sale1";
sale.Products = new[]
{
new Product
{
Name = "Product1",
Price = "10"
},
new Product
{
Name = "Product2",
Price = "15"
}
};
return sale;
})
.AddNode(sale => sale.Products.Sum(x => x.Price));
var total = await chain();
// Total: 25
Task
var sale = _repository.GetSale() // returns Task<Sale> type
.ToChain()
.AddNode(sale =>
{
sale.Total = sale.Products.Sum(x => x.Price);
return sale;
})
.AddNode(sale =>
{
sale.Tax = sale.Total * 0.12;
return sale;
});
IEnumerable
var sales = new List<Sale>();
var newSales = await sales.ToChain()
.AddNode(sales =>
{
return sales.Select(sale =>
{
sale.Total = sale.Products.Sum(x => x.Price);
return sale;
});
})
.AddNode(sales =>
{
return sales.Select(sale =>
{
sale.Tax = sale.Total * 0.12;
return sale;
});
});
IAsyncEnumerable
var asyncSales = await _repository.GetSalesAsync() // functions returns IAsyncEnumerable<Sale>
.ToChain()
.AddNode(async sales =>
{
await foreach(var sale in sales)
{
sale.Total = sale.Products.Sum(x => x.Price);
yield return sale;
}
})
.AddNode(async sales =>
{
await foreach(var sale in sales)
{
sale.Tax = sale.Total * 0.12;
yield return sale;
}
});
await foreach(var sale in asyncSales.WithCancellationToken(ct))
{
(...)
}
Or you can use .AddAsyncNode()
directly:
var asyncSales = await _repository.GetSalesAsync() // functions returns IAsyncEnumerable<Sale>
.ToChain()
.AddAsyncNode(sale =>
{
sale.Total = sale.Products.Sum(x => x.Price);
return sale;
})
.AddAsyncNode(sale =>
{
sale.Tax = sale.Total * 0.12;
yield return sale;
});
await foreach(var sale in asyncSales.WithCancellationToken(ct))
{
(...)
}
Special Nodes
Chunk Node for IAsyncEnumerable
NOTE: You can specify the total chunk with .Chunk() node
var asyncSales = await _repository.GetSalesAsync() // functions returns IAsyncEnumerable<Sale>
.ToChain()
.Chunk(10)
.AddNode(chunk =>
{
return chunk.Select(sale =>
{
sale.Total = sale.Products.Sum(x => x.Price);
return sale;
});
})
.AddNode(chunk =>
{
return chunk.Select(sale =>
{
sale.Tax = sale.Total * 0.12;
return sale;
});
});
await foreach(var chunk in asyncSales.WithCancellationToken(ct))
{
(...)
}
Wrapping Node functions
You can wrap functions and write like this with the following wrapping class:
var sale = new Sale();
await sale
.Checkout()
.AddTotal()
.AddTax()
.SetStatus(SaleStatus.Closed);
internal static class Wrappers
{
public static Chain<Sale> Checkout(this Sale sale, CancellationToken cancellationToken = default)
{
return sale.ToChain(cancellationToken)
.SetStatus(SaleStatus.Closing);
}
public static Chain<Sale> SetStatus(this Chain<Sale> chain, SaleStatus status)
{
return chain.AddNode(sale =>
{
sale.Status = status;
return sale;
});
}
public static Chain<Sale> AddTotal(this Chain<Sale> chain)
{
return chain.AddNode(sale =>
{
sale.Total = sale.Products.Sum(x => x.Price);
return sale;
});
}
public static Chain<Sale> AddTax(this Chain<Sale> chain)
{
return chain.AddNode(sale =>
{
sale.Tax = sale.Total * 0.12;
return sale;
});
}
}
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net8.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.