Skip to content

Breaking Change: Simplified interceptor implementation #39

@brunoblank

Description

@brunoblank

Hi,

Great work!

I have maintained my own class library for this and I believe the IAsyncInterceptor could be changed a bit to make using async / await less error prone.

Today (the helper function is needed and setting the ReturnValue):

public void InterceptAsynchronous(IInvocation invocation)
{
    invocation.ReturnValue = InternalInterceptAsynchronous(invocation);
}

private async Task InternalInterceptAsynchronous(IInvocation invocation)
{
    // Step 1. Do something prior to invocation.

    invocation.Proceed();
    var task = (Task)invocation.ReturnValue;
    await task;

    // Step 2. Do something after invocation.
}

This could be hidden in the library by changing the IAsyncInterceptor to:

    public interface IAsyncInterceptor
    {
        void InterceptAction(IActionInvocation invocation);

        Task InterceptAsyncAction(IAsyncActionInvocation invocation);

        Task<T> InterceptAsyncFunction<T>(IAsyncFunctionInvocation<T> invocation);

        T InterceptFunction<T>(IFunctionInvocation<T> invocation);
    }

Where the IInvocation interface's Proceed method matches the ReturnType

    public interface IAsyncFunctionInvocation<T> : IInvocationEx
    {
        Task<T> Proceed();
    }

    public interface IAsyncActionInvocation : IInvocationEx
    {
        Task Proceed();
    }
   ... etc ...

Now when implementing an interceptor, you would be able to use async / await directly.
Example:

    internal class MyAsyncInterceptor : IAsyncInterceptor
    {
        public void InterceptAction(IActionInvocation invocation)
        {
            invocation.Proceed();
        }

        public async Task InterceptAsyncAction(IAsyncActionInvocation invocation)
        {
            await Task.Delay(500);
            await invocation.Proceed();
            await Task.Delay(500);
        }

        public async Task<T> InterceptAsyncFunction<T>(IAsyncFunctionInvocation<T> invocation)
        {
            await Task.Delay(500);
            var rv = await invocation.Proceed();
            Console.WriteLine($"rv: {rv}");
            await Task.Delay(500);
            return rv;
        }

        public T InterceptFunction<T>(IFunctionInvocation<T> invocation)
        {
            return invocation.Proceed();
        }
    }

Is this something you would consider?

Thanks
/Bruno

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions