diff --git a/src/Hyperbee.Pipeline.Auth/Hyperbee.Pipeline.Auth.csproj b/src/Hyperbee.Pipeline.Auth/Hyperbee.Pipeline.Auth.csproj
index fb8b206..f69d011 100644
--- a/src/Hyperbee.Pipeline.Auth/Hyperbee.Pipeline.Auth.csproj
+++ b/src/Hyperbee.Pipeline.Auth/Hyperbee.Pipeline.Auth.csproj
@@ -32,7 +32,7 @@
True
\
-
+
all
diff --git a/src/Hyperbee.Pipeline/Binders/Abstractions/Binder.cs b/src/Hyperbee.Pipeline/Binders/Abstractions/Binder.cs
index eb97279..916a91d 100644
--- a/src/Hyperbee.Pipeline/Binders/Abstractions/Binder.cs
+++ b/src/Hyperbee.Pipeline/Binders/Abstractions/Binder.cs
@@ -1,26 +1,94 @@
-using Hyperbee.Pipeline.Context;
-using Hyperbee.Pipeline.Extensions.Implementation;
+using System.Linq.Expressions;
+using Hyperbee.Pipeline.Context;
+
+using static System.Linq.Expressions.Expression;
+using static Hyperbee.Expressions.AsyncExpression;
+
namespace Hyperbee.Pipeline.Binders.Abstractions;
internal abstract class Binder
{
- protected FunctionAsync Pipeline { get; }
- protected Action Configure { get; }
+ protected Expression> Pipeline { get; }
+ protected Expression> Configure { get; }
- protected Binder( FunctionAsync function, Action configure )
+ protected Binder( Expression> function, Expression> configure )
{
Pipeline = function;
Configure = configure;
}
- protected virtual async Task<(TOutput Result, bool Canceled)> ProcessPipelineAsync( IPipelineContext context, TInput argument )
+ // protected virtual Task<(TOutput Result, bool Canceled)> ProcessPipelineAsync( IPipelineContext context, TInput argument )
+ // {
+ // var result = await Pipeline( context, argument ).ConfigureAwait( false );
+ //
+ // var contextControl = (IPipelineContextControl) context;
+ // var canceled = contextControl.HandleCancellationRequested( result );
+ //
+ // return (canceled ? default : result, canceled);
+ // }
+
+ protected virtual Expression ProcessPipelineAsync( ParameterExpression context, ParameterExpression argument )
{
- var result = await Pipeline( context, argument ).ConfigureAwait( false );
+ var tupleCtor = typeof(ValueTuple).GetConstructor( [typeof(TOutput), typeof(bool)] )!;
+
+ var resultVariable = Variable( typeof( TOutput ), "result" );
+ var canceledVariable = Variable( typeof( bool ), "canceled" );
+
+ var contextControl = Convert( context , typeof( IPipelineContextControl ) );
- var contextControl = (IPipelineContextControl) context;
- var canceled = contextControl.HandleCancellationRequested( result );
+ var body = BlockAsync(
+ [resultVariable, canceledVariable],
+ Assign( resultVariable, Await( Invoke( Pipeline, context, argument ), configureAwait: false ) ),
+ Assign( canceledVariable, HandleCancellationRequested( contextControl, resultVariable ) ),
- return (canceled ? default : result, canceled);
+ Condition(
+ canceledVariable,
+ New( tupleCtor, Default( typeof( TOutput ) ), canceledVariable ),
+ New( tupleCtor, resultVariable, canceledVariable )
+ )
+ );
+
+ return body;
}
+
+
+
+ /*
+ public static bool HandleCancellationRequested( this IPipelineContextControl control, TOutput value )
+ {
+ if ( !control.CancellationToken.IsCancellationRequested )
+ return false;
+
+ if ( !control.HasCancellationValue )
+ control.CancellationValue = value;
+
+ return true;
+ }
+ */
+
+
+ private Expression HandleCancellationRequested( Expression contextControl, Expression resultVariable )
+ {
+ var hasCancellationValue = Property( contextControl, "HasCancellationValue" );
+ var cancellationTokenProperty = Property( contextControl, "CancellationToken" );
+ var cancellationValueProperty = Property( contextControl, "CancellationValue" );
+
+ var conditionalExpression = Condition(
+ Not( Property( cancellationTokenProperty, "IsCancellationRequested" ) ),
+ Constant( false ),
+
+ Block(
+ IfThen(
+ Not( hasCancellationValue ),
+ Assign( cancellationValueProperty, resultVariable )
+ ),
+ // After the assignment, return true
+ Constant( true )
+ )
+ );
+
+ return conditionalExpression;
+ }
+
}
diff --git a/src/Hyperbee.Pipeline/Binders/Abstractions/BlockBinder.cs b/src/Hyperbee.Pipeline/Binders/Abstractions/BlockBinder.cs
index 834d976..81965f6 100644
--- a/src/Hyperbee.Pipeline/Binders/Abstractions/BlockBinder.cs
+++ b/src/Hyperbee.Pipeline/Binders/Abstractions/BlockBinder.cs
@@ -1,10 +1,14 @@
-using Hyperbee.Pipeline.Context;
+using System.Linq.Expressions;
+using Hyperbee.Pipeline.Context;
+
+using static System.Linq.Expressions.Expression;
+using static Hyperbee.Expressions.AsyncExpression;
namespace Hyperbee.Pipeline.Binders.Abstractions;
internal abstract class BlockBinder : Binder
{
- protected BlockBinder( FunctionAsync function, Action configure )
+ protected BlockBinder( Expression> function, Expression> configure )
: base( function, configure )
{
}
@@ -13,8 +17,16 @@ protected BlockBinder( FunctionAsync function, Action ProcessBlockAsync( FunctionAsync blockFunction, IPipelineContext context, TArgument nextArgument )
+ // protected virtual async Task ProcessBlockAsync( Expression> blockFunction, IPipelineContext context, TArgument nextArgument )
+ // {
+ // return await blockFunction( context, nextArgument ).ConfigureAwait( false );
+ // }
+ protected virtual Expression> ProcessBlockAsync( Expression> blockFunction, ParameterExpression context, Expression nextArgument )
{
- return await blockFunction( context, nextArgument ).ConfigureAwait( false );
+ var body = BlockAsync(
+ Await( Invoke( blockFunction, context, nextArgument ), configureAwait: false )
+ );
+
+ return Lambda>( body );
}
}
diff --git a/src/Hyperbee.Pipeline/Binders/Abstractions/ConditionalBlockBinder.cs b/src/Hyperbee.Pipeline/Binders/Abstractions/ConditionalBlockBinder.cs
index 6f23e81..66520ff 100644
--- a/src/Hyperbee.Pipeline/Binders/Abstractions/ConditionalBlockBinder.cs
+++ b/src/Hyperbee.Pipeline/Binders/Abstractions/ConditionalBlockBinder.cs
@@ -1,31 +1,51 @@
-using System.Runtime.CompilerServices;
+using System.Linq.Expressions;
using Hyperbee.Pipeline.Context;
+using static System.Linq.Expressions.Expression;
namespace Hyperbee.Pipeline.Binders.Abstractions;
internal abstract class ConditionalBlockBinder : BlockBinder
{
- protected Function Condition { get; }
+ protected Expression> Condition { get; }
- protected ConditionalBlockBinder( Function condition, FunctionAsync function, Action configure )
+ protected ConditionalBlockBinder( Expression> condition, Expression> function, Expression> configure )
: base( function, configure )
{
Condition = condition;
}
- protected override async Task ProcessBlockAsync( FunctionAsync blockFunction, IPipelineContext context, TArgument nextArgument )
- {
- if ( Condition != null && !Condition( context, CastTypeArg( nextArgument ) ) )
- {
- return CastTypeArg( nextArgument );
- }
+ // protected override async Task ProcessBlockAsync( FunctionAsync blockFunction, IPipelineContext context, TArgument nextArgument )
+ // {
+ // if ( Condition != null && !Condition( context, CastTypeArg( nextArgument ) ) )
+ // {
+ // return CastTypeArg( nextArgument );
+ // }
+ //
+ // return await base.ProcessBlockAsync( blockFunction, context, nextArgument ).ConfigureAwait( false );
+ // }
- return await base.ProcessBlockAsync( blockFunction, context, nextArgument ).ConfigureAwait( false );
- }
+ // [MethodImpl( MethodImplOptions.AggressiveInlining )]
+ // private static TResult CastTypeArg( TType input )
+ // {
+ // return (TResult) (object) input;
+ // }
- [MethodImpl( MethodImplOptions.AggressiveInlining )]
- private static TResult CastTypeArg( TType input )
+ protected override Expression> ProcessBlockAsync(
+ Expression> blockFunction,
+ ParameterExpression context,
+ Expression nextArgument )
{
- return (TResult) (object) input;
+ if ( Condition == null )
+ return base.ProcessBlockAsync( blockFunction, context, nextArgument );
+
+ var nextArgumentExpression = Constant( nextArgument );
+
+ return Lambda>(
+ IfThenElse(
+ Not( Invoke( Condition, Constant( context ),
+ Convert( Convert( nextArgumentExpression, typeof(object) ), typeof(TOutput) ) ) ),
+ Convert( Convert( Constant( nextArgument ), typeof(object) ), typeof(TNext) ),
+ base.ProcessBlockAsync( blockFunction, context, nextArgument )
+ ) );
}
}
diff --git a/src/Hyperbee.Pipeline/Binders/Abstractions/StatementBinder.cs b/src/Hyperbee.Pipeline/Binders/Abstractions/StatementBinder.cs
index b5fb44c..0e3efaa 100644
--- a/src/Hyperbee.Pipeline/Binders/Abstractions/StatementBinder.cs
+++ b/src/Hyperbee.Pipeline/Binders/Abstractions/StatementBinder.cs
@@ -1,31 +1,124 @@
-using Hyperbee.Pipeline.Context;
-using Hyperbee.Pipeline.Extensions.Implementation;
+using System.Linq.Expressions;
+using Hyperbee.Pipeline.Context;
+using static System.Linq.Expressions.Expression;
+using static Hyperbee.Expressions.AsyncExpression;
namespace Hyperbee.Pipeline.Binders.Abstractions;
internal abstract class StatementBinder : Binder
{
- protected MiddlewareAsync