Create, compose and inject asynchronous behaviors in .Net Framework and .Net Core.
-
Create asynchronous behavior such as fiber, rate limiter, circuit breaker.
-
Compose these behaviors and use them as building blocks with aspect oriented programming.
-
Provide a lightweight way inject these behaviors to transform POCOs in actors.
Asynchronous behaviors are implemented using IDispatcher abstraction.
Composable Async provides various dispatchers implementation:
// Create dispatcher that catch all ArgumentException and retry for ever with a delay of 200 ms
var retryDispatcher = RetryPolicy.For<ArgumentException>()
.WithWaitBetweenRetry(TimeSpan.FromSeconds(0.2))
.ForEver();
See more at ComposableAsync.Resilient
// Create dispatcher that catch all ArgumentException and retry for ever with a delay of 200 ms
var retryDispatcher = CircuitBreakerPolicy.For<TimeoutException>()
.WithRetryAndTimeout(10, TimeSpan.FromMilliseconds(500));
See more at ComposableAsync.Resilient
// Create dispatcher that dispatch all action on the same thread
var fiberDispatcher = Fiber.CreateMonoThreadedFiber();
See more at ComposableAsync.Concurrent
// Create dispatcher that dispatch all action on the same thread
var timeConstraint = TimeLimiter.GetFromMaxCountByInterval(5, TimeSpan.FromSeconds(1));
See more at RateLimiter
Use then extension methods to create a dispatcher that will execute sequentially dispatchers
/// <summary>
/// Returns a composed dispatcher applying the given dispatchers sequentially
/// </summary>
/// <param name="dispatcher"></param>
/// <param name="others"></param>
/// <returns></returns>
public static IDispatcher Then(this IDispatcher dispatcher, IEnumerable<IDispatcher> others)
var composed = fiberDispatcher.Then(timeConstraint);
await fiberDispatcher;
// After the await, the code executes in the dispatcher context
// In this case the code will execute on the fiber thread
Console.WriteLine($"This is fiber thread {Thread.CurrentThread.ManagedThreadId}");
Transform a dispatcher into HttpMessageHandler with AsDelegatingHandler extension method:
/// Using time limiter nuget
var handler = TimeLimiter
.GetFromMaxCountByInterval(60, TimeSpan.FromMinutes(1))
.AsDelegatingHandler();
var client = new HttpClient(handler);
Using ComposableAsync.Factory
, with this option all methods call to the proxyfied object are wrapped using the provided dispatcher.
var retryDispatcher = RetryPolicy.For<SystemException>().ForEver();
var originalObject = new BusinessObject();
var proxyFactory = new ProxyFactory(retryDispatcher);
var proxyObject = proxyFactory.Build<IBusinessObject>(originalObject);
// The call to the originalObject will be wrapped into a retry policy for SystemException
var res = await proxyObject.Execute(cancellationToken);
ComposableAsync.Concurrent
also provides an actor factory based on fiber and proxy factory.
// Instantiate actor factory
var builder = new ActorFactoryBuilder();
var factory = builder.GetActorFactory(shared: false);
// When shared is true, all actor leaves in the same thread,
// when shared is false, each actor leaves in its own thread.
// Instantiate an actor from a POCO
var fooActor = fact.Build<IFoo>(new ConcreteFoo());
See more at ComposableAsync.Concurrent
For core functionality:
Install-Package ComposableAsync.Core
For factories:
Install-Package ComposableAsync.Factory
For actors:
Install-Package ComposableAsync.Concurrent
For retry and circuit-breaker:
Install-Package ComposableAsync.Resilient