// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNet.Builder; using Microsoft.Framework.DependencyInjection; using Xunit; namespace Microsoft.AspNet.Http.Extensions.Tests { public class UseWithServicesTests { [Fact] public async Task CallingUseThatAlsoTakesServices() { var builder = new ApplicationBuilder(new ServiceCollection() .AddScoped() .BuildServiceProvider()); ITestService theService = null; builder.Use(async (ctx, next, testService) => { theService = testService; await next(); }); var app = builder.Build(); await app(new DefaultHttpContext()); Assert.IsType(theService); } [Fact] public async Task ServicesArePerRequest() { var services = new ServiceCollection() .AddScoped() .BuildServiceProvider(); var builder = new ApplicationBuilder(services); builder.Use(async (ctx, next) => { var serviceScopeFactory = services.GetRequiredService(); using (var serviceScope = serviceScopeFactory.CreateScope()) { var priorApplicationServices = ctx.ApplicationServices; var priorRequestServices = ctx.ApplicationServices; ctx.ApplicationServices = services; ctx.RequestServices = serviceScope.ServiceProvider; try { await next(); } finally { ctx.ApplicationServices = priorApplicationServices; ctx.RequestServices = priorRequestServices; } } }); var testServicesA = new List(); builder.Use(async (HttpContext ctx, Func next, ITestService testService) => { testServicesA.Add(testService); await next(); }); var testServicesB = new List(); builder.Use(async (ctx, next, testService) => { testServicesB.Add(testService); await next(); }); var app = builder.Build(); await app(new DefaultHttpContext()); await app(new DefaultHttpContext()); Assert.Equal(2, testServicesA.Count); Assert.IsType(testServicesA[0]); Assert.IsType(testServicesA[1]); Assert.Equal(2, testServicesB.Count); Assert.IsType(testServicesB[0]); Assert.IsType(testServicesB[1]); Assert.Same(testServicesA[0], testServicesB[0]); Assert.Same(testServicesA[1], testServicesB[1]); Assert.NotSame(testServicesA[0], testServicesA[1]); Assert.NotSame(testServicesB[0], testServicesB[1]); } [Fact] public async Task InvokeMethodWillAllowPerRequestServices() { var services = new ServiceCollection() .AddScoped() .BuildServiceProvider(); var builder = new ApplicationBuilder(services); builder.UseMiddleware(); var app = builder.Build(); var ctx1 = new DefaultHttpContext(); await app(ctx1); var testService = ctx1.Items[typeof(ITestService)]; Assert.IsType(testService); } } public interface ITestService { } public class TestService : ITestService { } public class TestMiddleware { RequestDelegate _next; public TestMiddleware(RequestDelegate next) { _next = next; } public Task Invoke(HttpContext context, ITestService testService) { context.Items[typeof(ITestService)] = testService; return Task.FromResult(0); } } }