示例#1
0
        /// <summary>
        /// Collect a new interceptor.
        /// </summary>
        /// <param name="interceptor">The interceptor to collect.</param>
        /// <param name="order">The order in the interceptor chain to build.</param>
        /// <returns>The current inteceptor builder.</returns>
        /// <exception cref="ArgumentNullException">The specified <paramref name="interceptor"/> is null.</exception>
        public IInterceptorBuilder Use(InterceptorDelegate interceptor, int order)
        {
            Guard.ArgumentNotNull(interceptor, "interceptor");
            InterceptorDelegate wrapper = next => (async context =>
            {
                try
                {
                    await interceptor(next)(context);
                }
                catch (Exception ex)
                {
                    if (!context.ExceptionHandled)
                    {
                        throw new InterceptionException(Resources.ExceptionInterceptionError, ex);
                    }
                    else
                    {
                        throw ex;
                    }
                }
            });

            _interceptors.Add(new Tuple <int, InterceptorDelegate>(order, wrapper));
            return(this);
        }
示例#2
0
        protected override Task InterceptAsync(IInvocation invocation, Func <IInvocation, Task> proceed)
        {
            var invocationContext  = new DynamicProxyInvocationContext(invocation);
            InterceptDelegate next = context => proceed(invocation);

            return(_interceptor(next)(invocationContext));
        }
示例#3
0
        /// <summary>
        ///  Invoke interceptor and target method.
        /// </summary>
        /// <param name="interceptor">A <see cref="InterceptorDelegate"/> representing interceptor applied to target method.</param>
        /// <param name="handler">A <see cref="InterceptDelegate"/> used to invoke the target method.</param>
        /// <param name="context">A <see cref="InvocationContext"/> representing the current method invocation context.</param>
        /// <returns>The task to invoke interceptor and target method.</returns>
        public static Task InvokeHandler(InterceptorDelegate interceptor, InterceptDelegate handler, InvocationContext context)
        {
            async Task Wrap(InvocationContext invocationContext)
            {
                await handler(invocationContext);

                if (invocationContext.ReturnValue is Task task)
                {
                    await task;
                }
            }

            return(interceptor(Wrap)(context));
        }
示例#4
0
        /// <summary>
        ///  Invoke interceptor and target method.
        /// </summary>
        /// <param name="interceptor">A <see cref="InterceptorDelegate"/> representing interceptor applied to target method.</param>
        /// <param name="handler">A <see cref="InterceptDelegate"/> used to invoke the target method.</param>
        /// <param name="context">A <see cref="InvocationContext"/> representing the current method invocation context.</param>
        /// <returns>The task to invoke interceptor and target method.</returns>
        public static Task InvokeHandler(InterceptorDelegate interceptor, InterceptDelegate handler, InvocationContext context)
        {
            InterceptDelegate wrapper = async _ => {
                await handler(_);

                var task = _.ReturnValue as Task;
                if (null != task)
                {
                    await task;
                }
            };

            return(interceptor(wrapper)(context));
        }
示例#5
0
        /// <summary>
        /// Register the interceptor of <paramref name="interceptorType"/> to specified interceptor chain builder.
        /// </summary>
        /// <param name="builder">The interceptor chain builder to which the interceptor is registered.</param>
        /// <param name="interceptorType">The interceptor type.</param>
        /// <param name="order">The order for the registered interceptor in the built chain.</param>
        /// <param name="arguments">The non-injected arguments passes to the constructor.</param>
        /// <returns>The interceptor chain builder with registered interceptor.</returns>
        /// <exception cref="ArgumentNullException">The argument <paramref name="builder"/> is null.</exception>
        /// <exception cref="ArgumentNullException">The argument <paramref name="interceptorType"/> is null.</exception>
        public static IInterceptorChainBuilder Use(this IInterceptorChainBuilder builder, Type interceptorType, int order, params object[] arguments)
        {
            Guard.ArgumentNotNull(builder, nameof(builder));
            Guard.ArgumentNotNull(interceptorType, nameof(interceptorType));
            object instance = ActivatorUtilities.CreateInstance(builder.ServiceProvider, interceptorType, arguments);

            InterceptorDelegate interceptor = next =>
            {
                return(async context =>
                {
                    context.Next = next;
                    InvokeDelegate invoker;
                    if (TryGetInvoke(interceptorType, out invoker))
                    {
                        await invoker(instance, context, builder.ServiceProvider);
                    }
                    else
                    {
                        throw new ArgumentException("Invalid interceptor type", "interceptorType");
                    }
                });
            };

            return(builder.Use(interceptor, order));
        }
示例#6
0
        public void GetInterceptors()
        {
            var invokeMethod = typeof(Foobar).GetMethod("Invoke");
            var fooProperty  = typeof(Foobar).GetProperty("Foo");

            InterceptorDelegate interceptor = next => null;
            var interceptors = new Dictionary <MethodInfo, InterceptorDelegate>
            {
                [invokeMethod]          = interceptor,
                [fooProperty.GetMethod] = interceptor
            };

            var interception = new InterceptorDecoration(interceptors, typeof(Foobar).GetInterfaceMap(typeof(IFoobar)));

            Assert.False(interception.IsEmpty);
            Assert.True(interception.Contains(invokeMethod));
            Assert.True(interception.Contains(fooProperty.GetMethod));
            Assert.False(interception.Contains(fooProperty.SetMethod));

            Assert.True(interception.IsInterceptable(invokeMethod));
            Assert.True(interception.IsInterceptable(fooProperty.GetMethod));
            Assert.False(interception.IsInterceptable(fooProperty.SetMethod));

            Assert.Same(interceptor, interception.GetInterceptor(invokeMethod));
            Assert.Same(interceptor, interception.GetInterceptor(fooProperty.GetMethod));

            Assert.Same(typeof(Foobar).GetMethod("Invoke"), interception.GetTargetMethod(typeof(IFoobar).GetMethod("Invoke")));
        }
示例#7
0
        /// <summary>
        /// Method to unregister an interceptor
        /// </summary>
        /// <param name="direction">Defines if interceptor is for: publish or subscribe</param>
        /// <param name="registrationGuid">Goid which was returned from the register call</param>
        public static void UnRegister(InterceptDirection direction, Guid registrationGuid)
        {
            if (direction != InterceptDirection.Publish && direction != InterceptDirection.Subscribe)
            {
                return;
            }

            if (direction == InterceptDirection.Subscribe)
            {
                if (subscribeRegistrationGuid == registrationGuid)
                {
                    subscribeInterceptor      = null;
                    subscribeRegistrationGuid = Guid.Empty;
                }
            }
            else
            {
                if (publishRegistrationGuid == registrationGuid)
                {
                    publishInterceptor      = null;
                    publishRegistrationGuid = Guid.Empty;
                }
            }

            return;
        }
        public async Task <TResult> InvokeAsync <TResult>(InterceptorDelegate interceptor, InvocationContext context)
        {
            if (_collections.TryGetValue(context.Method, out InterceptorMiddleware middleware))
            {
                await middleware(interceptor)(context);
            }
            else
            {
                await interceptor(context);
            }

            if (context.Return is Task <TResult> taskWithResult)
            {
                return(await taskWithResult);
            }
            else if (context.Return is Task task)
            {
                await task;
                return(default(TResult));
            }
            else
            {
                throw new InvalidCastException($"无法将返回值类型转换为{typeof(Task<TResult>)}");
            }
        }
示例#9
0
        public void Wrap()
        {
            var fooMethod   = typeof(IFoobar).GetMethod("Foo");
            var barProperty = typeof(IFoobar).GetProperty("Bar");

            InterceptorDelegate interceptor = next => (context => Task.Run(() => _flag++));
            var interceptors = new Dictionary <MethodInfo, InterceptorDelegate>
            {
                [fooMethod]             = interceptor,
                [barProperty.GetMethod] = interceptor
            };
            var interception = new InterceptorDecoration(interceptors, typeof(Foobar).GetInterfaceMap(typeof(IFoobar)));

            var proxy = new InterfaceDynamicProxyGenerator(new DynamicProxyFactoryCache())
                        .Wrap(typeof(IFoobar), new Foobar(), interception)
                        as IFoobar;

            _flag = 0;
            proxy.Foo();
            Assert.Equal(1, _flag);
            var bar = proxy.Bar;

            Assert.Equal(2, _flag);
            proxy.Bar = "111";
            Assert.Equal(2, _flag);
        }
示例#10
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PropertyBasedInterceptorDecoration"/> class.
        /// </summary>
        /// <param name="property">The property.</param>
        /// <param name="getMethodBasedInterceptor">The get method based interceptor.</param>
        /// <param name="setMethodBasedInterceptor">The set method based interceptor.</param>
        /// <exception cref="ArgumentNullException"> Specified <paramref name="property"/> is null.</exception>
        /// <exception cref="ArgumentNullException"> Specified <paramref name="getMethodBasedInterceptor"/> and <paramref name="setMethodBasedInterceptor"/> are both null.</exception>
        public PropertyBasedInterceptorDecoration(
            PropertyInfo property,
            InterceptorDelegate getMethodBasedInterceptor,
            InterceptorDelegate setMethodBasedInterceptor)
        {
            this.Property = Guard.ArgumentNotNull(property, nameof(property));
            if (getMethodBasedInterceptor == null && setMethodBasedInterceptor == null)
            {
                throw new ArgumentException(Resources.ExceptionGetAndSetMethodBasedInterceptorCannotBeNull);
            }

            if (getMethodBasedInterceptor != null)
            {
                var getMethod = property.GetMethod;
                if (null != getMethod)
                {
                    this.GetMethodBasedInterceptor = new MethodBasedInterceptorDecoration(getMethod, getMethodBasedInterceptor);
                }
            }

            if (setMethodBasedInterceptor != null)
            {
                var setMethod = property.SetMethod;
                if (null != setMethod)
                {
                    this.SetMethodBasedInterceptor = new MethodBasedInterceptorDecoration(setMethod, setMethodBasedInterceptor);
                }
            }
        }
示例#11
0
        public override async Task Intercept(InvocationContext context, InterceptorDelegate next)
        {
            this.Log.Write("方法执行之前,当前参数值:" + string.Join(",", context.Arguments));
            await next(context);

            Thread.Sleep(1000);
            this.Log.Write("方法执行之后,当前返回值:" + context.Return);
        }
示例#12
0
        private T CreateProxy <T>(T target, InterceptorDelegate interceptor, MethodInfo method)
        {
            var methodBasedInterceptor = new MethodBasedInterceptorDecoration(method, interceptor);
            var decoration             = new InterceptorDecoration(new MethodBasedInterceptorDecoration[] { methodBasedInterceptor }, null);
            var generator = DynamicProxyClassGenerator.CreateInterfaceGenerator(typeof(T), decoration);
            var proxyType = generator.GenerateProxyType();

            return((T)Activator.CreateInstance(proxyType, target, decoration));
        }
示例#13
0
        private T1 CreateProxy <T1, T2>(T1 target, InterceptorDelegate interceptor, Expression <Func <T1, T2> > propertyAccessor)
        {
            var property = (PropertyInfo)((MemberExpression)propertyAccessor.Body).Member;
            var propertyBasedInterceptor = new PropertyBasedInterceptorDecoration(property, interceptor, interceptor);
            var decoration = new InterceptorDecoration(null, new PropertyBasedInterceptorDecoration[] { propertyBasedInterceptor });
            var generator  = DynamicProxyClassGenerator.CreateInterfaceGenerator(typeof(T1), decoration);
            var proxyType  = generator.GenerateProxyType();

            return((T1)Activator.CreateInstance(proxyType, target, decoration));
        }
示例#14
0
        public void TestGenericType()
        {
            //Foobar<T>()
            string flag = "";
            InterceptorDelegate interceptor = next => (context => { flag = "Foobar"; return(next(context)); });
            var proxy = this.CreateProxy <ICalculator <int> >(new IntCalculator(), interceptor, _ => _.Add(0, 0));

            Assert.Equal(3, proxy.Add(1, 2));
            Assert.Equal("Foobar", flag);
        }
示例#15
0
        public void TestGenericMethod()
        {
            var    method = typeof(Calculator).GetMethod("Multiply");
            string flag   = "";
            InterceptorDelegate interceptor = next => (context => { flag = "Foobar"; return(next(context)); });
            var decoration = new InterceptorDecoration(new MethodBasedInterceptorDecoration[] { new MethodBasedInterceptorDecoration(method, interceptor) }, null);
            var proxy      = this.CreateProxy <Calculator>(interceptor, typeof(Calculator).GetMethod("Multiply"));

            Assert.Equal(2, proxy.Multiply(1, 2));
            Assert.Equal("Foobar", flag);
        }
示例#16
0
        private T CreateProxy <T>(InterceptorDelegate interceptor, MethodInfo method)
        {
            var methodBasedInterceptor = new MethodBasedInterceptorDecoration(method, interceptor);
            var decoration             = new InterceptorDecoration(new MethodBasedInterceptorDecoration[] { methodBasedInterceptor }, null);
            var generator = DynamicProxyClassGenerator.CreateVirtualMethodGenerator(typeof(T), decoration);
            var proxyType = generator.GenerateProxyType();
            var proxy     = (T)Activator.CreateInstance(proxyType);

            ((IInterceptorsInitializer)proxy).SetInterceptors(decoration);
            return(proxy);
        }
示例#17
0
        private T1 CreateProxy <T1, T2>(InterceptorDelegate interceptor, Expression <Func <T1, T2> > propertyAccessor)
        {
            var property = (PropertyInfo)((MemberExpression)propertyAccessor.Body).Member;
            var propertyBasedInterceptor = new PropertyBasedInterceptorDecoration(property, interceptor, interceptor);
            var decoration = new InterceptorDecoration(null, new PropertyBasedInterceptorDecoration[] { propertyBasedInterceptor });
            var generator  = DynamicProxyClassGenerator.CreateVirtualMethodGenerator(typeof(T1), decoration);
            var proxyType  = generator.GenerateProxyType();
            var proxy      = (T1)Activator.CreateInstance(proxyType);

            ((IInterceptorsInitializer)proxy).SetInterceptors(decoration);
            return(proxy);
        }
示例#18
0
        public void TestProperty()
        {
            string flag = "";
            InterceptorDelegate interceptor = next => (context => { flag = "Foobar"; return(next(context)); });
            var proxy = this.CreateProxy <DataAccessor, string>(interceptor, _ => _.Data);

            Assert.Equal("Foobar", proxy.Data);

            flag       = "";
            proxy.Data = "123";
            Assert.Equal("Foobar", flag);
        }
示例#19
0
        public void TestIndex()
        {
            string flag = "";
            InterceptorDelegate interceptor = next => (context => { flag = "Foobar"; return(next(context)); });
            var proxy = this.CreateProxy <IDataAccessor>(new DataAccessor(), interceptor, typeof(IDataAccessor).GetProperty("Item", typeof(string)).GetMethod);

            Assert.Equal("Foobar", proxy[0]);
            Assert.Equal("Foobar", flag);

            flag     = "";
            proxy    = this.CreateProxy <IDataAccessor>(new DataAccessor(), interceptor, typeof(IDataAccessor).GetProperty("Item", typeof(string)).SetMethod);
            proxy[0] = "abc";
            Assert.Equal("Foobar", flag);
        }
示例#20
0
        /// <summary>
        ///  Invoke interceptor and target method.
        /// </summary>
        /// <param name="interceptor">A <see cref="InterceptorDelegate"/> representing interceptor applied to target method.</param>
        /// <param name="handler">A <see cref="InterceptDelegate"/> used to invoke the target method.</param>
        /// <param name="context">A <see cref="InvocationContext"/> representing the current method invocation context.</param>
        /// <returns>The task to invoke interceptor and target method.</returns>
        public static Task InvokeHandler(InterceptorDelegate interceptor, InterceptDelegate handler, InvocationContext context)
        {
            InterceptDelegate wrapper = async _ =>
            {
                await handler(_);

                var task = _.ReturnValue as Task;
                if (null != task)
                {
                    await task;
                }
            };

            var resultTask = interceptor(wrapper)(context);
            // throw inner InterceptorException
            var agregateException = resultTask.Exception;

            if (agregateException != null &&
                agregateException.InnerExceptions.Any(ex => (ex is InterceptorException) && (ex as InterceptorException).RequireThrow))
            {
                throw resultTask.Exception;
            }
            return(resultTask);
        }
示例#21
0
        public InterceptorDelegate Build()
        {
            var interceptors = this._interceptors.OrderByDescending(p => p.Key).Select(p => p.Value);

            InterceptorDelegate intercept = _next =>
            {
                var current = _next;
                foreach (var item in interceptors)
                {
                    current = item(current);
                }
                return(current);
            };

            return(intercept);
        }
示例#22
0
        /// <summary>
        /// Add a new interceptor to interceptor chain.
        /// </summary>
        /// <param name="builder">The interceptor builder.</param>
        /// <param name="interceptorType">The type of interceptor.</param>
        /// <param name="order">The order to determine the position in the interceptor chain.</param>
        /// <param name="arguments">The arguments passed to constructor.</param>
        /// <returns>The current interceptor builder.</returns>
        /// <exception cref="ArgumentNullException">The specified <paramref name="builder"/> is null.</exception>
        /// <exception cref="ArgumentNullException">The specified <paramref name="interceptorType"/> is null.</exception>
        /// <exception cref="ArgumentException">The specified <paramref name="interceptorType"/> is not a valid interceptor.
        /// <para>The valid interceptor class should be defined as below.</para>
        /// <code>
        /// public class FoobarInterceptor
        /// {
        ///     private InterceptDelegate _next;
        ///     private IFoo              _foo;
        ///
        ///     public FoobarInterceptor(InterceptDelegate next, IFoo foo)
        ///     {
        ///         _next = next;
        ///         _foo = foo;
        ///     }
        ///
        ///     public Task InvokeAsync(InvocationContext context, IBar bar)
        ///     {
        ///         ...
        ///         await _next(context);
        ///     }
        /// }
        /// </code>
        /// </exception>
        public static IInterceptorBuilder Use(this IInterceptorBuilder builder, Type interceptorType, int order, params object[] arguments)
        {
            Guard.ArgumentNotNull(builder, "builder");
            Guard.ArgumentNotNull(interceptorType, "interceptorType");
            InterceptorDelegate interceptor = next => (async context =>
            {
                object[] newArguments = new object[arguments.Length + 1];
                newArguments[0] = next;
                arguments.CopyTo(newArguments, 1);
                object instance = ActivatorUtilities.CreateInstance(builder.ServiceProvider, interceptorType, newArguments);
                InvokeDelegate factory = GetFactory(interceptorType);
                await factory(instance, context, builder.ServiceProvider);
            });

            return(builder.Use(interceptor, order));
        }
示例#23
0
        /// <summary>
        /// Method used to register an interceptor with Wsp. Only one interceptor is permitted.
        /// </summary>
        /// <param name="direction">Defines the direction the interceptor is registering for: publish or subscribe</param>
        /// <param name="interceptor">Delegate which Wsp will call for interception</param>
        /// <param name="onNextPrivate">Delegate to publish events which bypass interceptor logic</param>
        /// <returns>Guid needed to unregister</returns>
        public static Guid Register(InterceptDirection direction, InterceptorDelegate interceptor, out OnNextPrivate onNextPrivate)
        {
            WspEventPublish eventPublish = new WspEventPublish();

            onNextPrivate = eventPublish.OnNextPrivate;

            if (direction != InterceptDirection.Publish && direction != InterceptDirection.Subscribe)
            {
                onNextPrivate = null;

                return(Guid.Empty);
            }

            if (direction == InterceptDirection.Subscribe)
            {
                if (subscribeRegistrationGuid == Guid.Empty)
                {
                    subscribeInterceptor      = interceptor;
                    subscribeRegistrationGuid = Guid.NewGuid();

                    return(subscribeRegistrationGuid);
                }
                else
                {
                    onNextPrivate = null;

                    return(Guid.Empty);
                }
            }
            else
            {
                if (publishRegistrationGuid == Guid.Empty)
                {
                    publishInterceptor      = interceptor;
                    publishRegistrationGuid = Guid.NewGuid();

                    return(publishRegistrationGuid);
                }
                else
                {
                    onNextPrivate = null;

                    return(Guid.Empty);
                }
            }
        }
示例#24
0
        public InterceptorChainBuilder Use(Type interceptorType, int order, params object[] args)
        {
            var invokeMethod = interceptorType.GetMethods().Where(p => p.Name == "InvokeAsync" && p.ReturnType == typeof(Task) && p.GetParameters().FirstOrDefault()?.ParameterType == typeof(InvocationContext)).FirstOrDefault();

            if (invokeMethod == null)
            {
                return(this);
            }


            //InvokeDelegate(object interceptor, InvocationContext context, IServiceProvider serviceProvider);

            ParameterExpression interceptor     = Expression.Parameter(typeof(object), "interceptor");
            ParameterExpression context         = Expression.Parameter(typeof(InvocationContext), "context");
            ParameterExpression serviceProvider = Expression.Parameter(typeof(IServiceProvider), "serviceProvider");

            var invArgs = invokeMethod.GetParameters().Select(p =>
            {
                if (p.ParameterType == typeof(InvocationContext))
                {
                    return((Expression)context);
                }

                Expression serviceType    = Expression.Constant(p.ParameterType, typeof(Type));
                Expression callGetService = Expression.Call(_getServiceMethod, serviceProvider, serviceType);
                return((Expression)Expression.Convert(callGetService, p.ParameterType));
            });

            Expression instanceConvert = Expression.Convert(interceptor, interceptorType);
            var        invoke          = Expression.Call(instanceConvert, invokeMethod, invArgs);
            var        invoker         = Expression.Lambda <InvokeDelegate>(invoke, interceptor, context, serviceProvider).Compile();

            InterceptorDelegate interceptorDelegate = _next =>
            {
                var instance        = ActivatorUtilities.CreateInstance(this.ServiceProvider, interceptorType, _next);
                InterceptDelegate _ = async invContext =>
                {
                    await invoker(instance, invContext, this.ServiceProvider);
                };

                return(_);
            };

            this._interceptors.Add(order, interceptorDelegate);
            return(this);
        }
示例#25
0
        public void Intercept(IInvocation invocation)
        {
            CastleInvocationContext invocationContext = new CastleInvocationContext(invocation, _serviceProvider);
            InterceptDelegate       next = context => ((CastleInvocationContext)context).ProceedAsync();

            try
            {
                _interceptor(next)(invocationContext).Wait();
            }
            catch (AggregateException ex)
            {
                throw ex?.InnerException ?? ex;
            }
            catch
            {
                throw;
            }
        }
示例#26
0
        private InterceptorDecoration GetInterceptors(Type typeToIntercept, Dictionary <MethodInfo, IInterceptorProvider[]> providers)
        {
            var methodBasedDecorations   = new List <MethodBasedInterceptorDecoration>();
            var propertyBasedDecorations = new List <PropertyBasedInterceptorDecoration>();

            foreach (var methodInfo in typeToIntercept.GetTypeInfo().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
            {
                if (methodInfo.IsSpecialName || methodInfo.DeclaringType == typeof(object))
                {
                    continue;
                }

                if (!providers.TryGetValue(methodInfo, out var methodProviders))
                {
                    continue;
                }
                var intercecptor = this.BuildInterceptor(methodProviders);
                methodBasedDecorations.Add(new MethodBasedInterceptorDecoration(methodInfo, intercecptor));
            }

            foreach (var property in typeToIntercept.GetTypeInfo().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
            {
                InterceptorDelegate interceptorOfGetMethod = null;
                InterceptorDelegate interceptorOfSetMethod = null;
                var getMethod = property.GetMethod;
                var setMethod = property.SetMethod;
                if (null != getMethod && providers.TryGetValue(getMethod, out var getMethodProviders))
                {
                    interceptorOfGetMethod = this.BuildInterceptor(getMethodProviders);
                }

                if (null != setMethod && providers.TryGetValue(setMethod, out var setMethodProviders))
                {
                    interceptorOfSetMethod = this.BuildInterceptor(setMethodProviders);
                }

                if (null != interceptorOfGetMethod || null != interceptorOfSetMethod)
                {
                    propertyBasedDecorations.Add(new PropertyBasedInterceptorDecoration(property, interceptorOfGetMethod, interceptorOfSetMethod));
                }
            }
            return(new InterceptorDecoration(methodBasedDecorations, propertyBasedDecorations));
        }
        public static IInterceptorChainBuilder Use(this IInterceptorChainBuilder builder, Type interceptorType, int order, params object[] arguments)
        {
            InterceptorDelegate interceptor = next => (async context => {
                object[] newArguments = new object[arguments.Length + 1];
                newArguments[0] = next;
                arguments.CopyTo(newArguments, 1);
                object instance = ActivatorUtilities.CreateInstance(builder.ServiceProvider, interceptorType, newArguments);
                InvokeDelegate invoker;
                if (TryGetInvoke(interceptorType, out invoker))
                {
                    await invoker(instance, context, builder.ServiceProvider);
                }
                else
                {
                    throw new ArgumentException("Invalid interceptor type", "interceptorType");
                }
            });

            return(builder.Use(interceptor, order));
        }
示例#28
0
        public void TestParameterType()
        {
            //General
            string flag = "";
            InterceptorDelegate interceptor = next => (context => { flag = "Foobar"; return(next(context)); });
            var proxy = this.CreateProxy <ICalculator>(new Calculator(), interceptor, _ => _.Add(0, 0));

            Assert.Equal(3, proxy.Add(1, 2));
            Assert.Equal("Foobar", flag);

            //ref, out
            double x = 1;
            double y = 2;
            double result;

            flag  = "";
            proxy = this.CreateProxy <ICalculator>(new Calculator(), interceptor, _ => _.Substract(ref x, ref y, out result));
            proxy.Substract(ref x, ref y, out result);
            Assert.Equal(-1, result);
        }
示例#29
0
        public async void TestReturnType()
        {
            //Void
            string flag1 = "";
            string flag2 = "";
            InterceptorDelegate interceptor = next => (context => { flag1 = "Foobar"; return(next(context)); });
            var proxy = this.CreateProxy <Foobar>(interceptor, _ => _.Invoke1());

            proxy.Action = () => flag2 = "Foobar";
            proxy.Invoke1();
            Assert.Equal("Foobar", flag1);
            Assert.Equal("Foobar", flag2);

            //String
            flag1        = "";
            flag2        = "";
            proxy        = this.CreateProxy <Foobar>(interceptor, _ => _.Invoke2());
            proxy.Action = () => flag2 = "Foobar";
            Assert.Equal("Foobar", proxy.Invoke2());
            Assert.Equal("Foobar", flag1);
            Assert.Equal("Foobar", flag2);

            //Task
            flag1        = "";
            flag2        = "";
            proxy        = this.CreateProxy <Foobar>(interceptor, _ => _.Invoke3());
            proxy.Action = () => flag2 = "Foobar";
            await proxy.Invoke3();

            Assert.Equal("Foobar", flag1);
            Assert.Equal("Foobar", flag2);

            //Task<T>
            flag1        = "";
            flag2        = "";
            proxy        = this.CreateProxy <Foobar>(interceptor, _ => _.Invoke4());
            proxy.Action = () => flag2 = "Foobar";
            Assert.Equal("Foobar", await proxy.Invoke4());
            Assert.Equal("Foobar", flag1);
            Assert.Equal("Foobar", flag2);
        }
        public TResult Invoke <TResult>(InterceptorDelegate interceptor, InvocationContext context)
        {
            Task task = null;

            if (_collections.TryGetValue(context.Method, out InterceptorMiddleware middleware))
            {
                task = middleware(interceptor)(context);
            }
            else
            {
                task = interceptor(context);
            }
            if (task.IsFaulted)
            {
                throw task.Exception.InnerException;
            }
            if (!task.IsCompleted)
            {
                NoSyncContextScope.Run(task);
            }
            return((TResult)context.Return);
        }