Interceptor State
InterceptorState
is a state class intended to carry information between the different stages of method interception.
- Before Execution
Before the real, decorated, service instance method is invoked, the interceptor is given the opportunity to create a state object that can be later accessed after method invocation, or if the method faults (throws an exception). The interceptor can also force the invocation of the instance method to be skipped by setting a 'handled' result.
- After Execution
After the service instance method has been invoked, or skipped, the interceptor's state can be inspected to perform a post-processing task, or replace the final result to be returned to the caller.
- Faulted Execution
If an exception is thrown during method invocation, the interceptor is given the opportunity to inspect the state instance and perform custom fault handling.
Typed vs Non-Typed
There are two flavours of InterceptorState
; typed and non-typed. The following table provides a summary of when each will be used.
Interceptor Type | Method Return Type | State Type |
---|---|---|
Class-level | All |
|
Method-level |
|
|
|
| |
|
| |
|
|
Key Features
IsHandled
This is a boolean flag that can be set at the time of creating the initial state object, before the decorated instance method is called. When set to true
, the interceptor will skip calling the instance method. The interceptor is responsible for providing the result to be returned to the caller, by calling the SetResult()
method.
GetResult()
There are two overloads of GetResult()
:
All results are stored as object
on the InterceptorState
. The GetResult<TResult>()
version is a convenience method that unboxes the result for you.
SetResult()
A result can be set on the InterceptorState
using the following method:
A result will be set explicitly by the interceptor when the decorated instance method is called, or by the handler within the before/after invocation methods.
Result
This is a typed, convenience, property that is only applicable to InterceptorState<TResult>
state types, and implemented in terms of GetResult()
and SetResult()
, like so:.
Async Methods
Results for async
methods are worthy of special mention since they are stored on the state instance as a Task<TResult>
.
Getting the result:
- Class level interceptors
- // Is of type Task<TResult> var stateResult = state.GetResult<TResult>(); // Referencing '.Result' is safe since the task has already completed var value = stateResult.Result;
- Method level interceptors
- // Is of type Task<TResult> var stateResult = state.Result; // Referencing '.Result' is safe since the task has already completed var value = stateResult.Result;
Setting the result:
- Class level interceptors
- var result = ... // some value // Must assign as Task<TResult> state.SetResult(Task.FromResult(result));
- Method level interceptors
- var result = ... // some value // Must assign as Task<TResult> state.Result = Task.FromResult(result);