示例#1
0
        private static ITaskMiddleware GetMiddleware(
            TaskMiddlewareDescriptor descriptor, IServiceProvider serviceProvider)
        {
            if (!s_factories.TryGetValue(descriptor, out Func <IServiceProvider, ITaskMiddleware> factory))
            {
                if (descriptor.Func is object)
                {
                    var middleware = new FuncMiddleware(descriptor.Func);
                    factory = s_factories.GetOrAdd(descriptor, _ => middleware);
                    return(middleware);
                }
                else if (serviceProvider.GetService(descriptor.Type) is ITaskMiddleware fetchedMiddleware)
                {
                    s_factories[descriptor] = sp => (ITaskMiddleware)sp.GetRequiredService(descriptor.Type);
                    return(fetchedMiddleware);
                }
                else
                {
                    ObjectFactory objectFactory = ActivatorUtilities.CreateFactory(
                        descriptor.Type, Array.Empty <Type>());
                    factory = s_factories.GetOrAdd(
                        descriptor, sp => (ITaskMiddleware)objectFactory.Invoke(sp, Array.Empty <object>()));
                    return(factory.Invoke(serviceProvider));
                }
            }

            return(factory.Invoke(serviceProvider));
        }
        public async Task Run_Func_ExecutesTwice()
        {
            // arrange
            var next1    = new NextFunc();
            var next2    = new NextFunc();
            int executed = 0;

            Task Middleware(DispatchMiddlewareContext context, Func <Task> next)
            {
                executed++;
                return(next());
            }

            var descriptor = new TaskMiddlewareDescriptor(Middleware);
            var context    = CreateContext();

            // act
            await TaskMiddlewareRunner.RunAsync(descriptor, context, next1.InvokeAsync);

            await TaskMiddlewareRunner.RunAsync(descriptor, context, next2.InvokeAsync);

            // assert
            executed.Should().Be(2);
            next1.ExecutionCount.Should().Be(1);
            next2.ExecutionCount.Should().Be(1);
        }
        public async Task Run_Type_Executes(bool addMiddleware)
        {
            // arrange
            var next       = new NextFunc();
            var descriptor = TaskMiddlewareDescriptor.Create <TestMiddleware>();

            IServiceProvider serviceProvider = CreateServiceProvider(addMiddleware);
            var context = CreateContext(serviceProvider);

            // act
            await TaskMiddlewareRunner.RunAsync(descriptor, context, next.InvokeAsync);

            // assert
            var tracker = serviceProvider.GetRequiredService <ExecutionTracker>();

            tracker.ExecutionCount.Should().Be(1);
            next.ExecutionCount.Should().Be(1);
        }
示例#4
0
        /// <summary>
        /// Runs the middleware described by <see cref="TaskMiddlewareDescriptor"/>.
        /// </summary>
        /// <param name="descriptor">The task middleware to find and run.</param>
        /// <param name="context">The dispatch middleware context.</param>
        /// <param name="next">The next middleware callback.</param>
        /// <returns>A task that completes when the middleware has finished executing.</returns>
        public static Task RunAsync(
            TaskMiddlewareDescriptor descriptor, DispatchMiddlewareContext context, Func <Task> next)
        {
            Check.NotNull(descriptor, nameof(descriptor));
            Check.NotNull(context, nameof(context));
            Check.NotNull(next, nameof(next));

            IServiceProvider serviceProvider = context.GetProperty <IServiceProvider>();
            ITaskMiddleware  middleware      = GetMiddleware(descriptor, serviceProvider);

            if (middleware is null)
            {
                // This _should not_ be possible, as TaskMiddlewareDescriptor is designed to only be constructable with
                // valid values. But a good sanity check here.
                ILogger logger  = serviceProvider.CreateLogger(typeof(TaskMiddlewareRunner));
                string  message = Strings.MiddlewareCreationFailed(descriptor);
                logger.LogError(message);
                throw new InvalidOperationException(message); // TODO: maybe a better exception type.
            }

            return(middleware.InvokeAsync(context, next));
        }
 public async Task Run_NullNext_Throws()
 {
     var         descriptor = new TaskMiddlewareDescriptor((c, n) => Task.CompletedTask);
     Func <Task> act        = () => TaskMiddlewareRunner.RunAsync(descriptor, CreateContext(), null);
     await act.Should().ThrowExactlyAsync <ArgumentNullException>();
 }