// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; using System.Linq; using System.Reflection; using Microsoft.AspNetCore.Mvc.ApplicationParts; using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.Internal; using Microsoft.AspNetCore.Mvc.MvcServiceCollectionExtensionsTestControllers; using Microsoft.Extensions.DependencyInjection; using Moq; using Xunit; namespace Microsoft.AspNetCore.Mvc { public class MvcBuilderExtensionsTest { [Fact] public void AddApplicationPart_AddsAnApplicationPart_ToTheListOfPartsOnTheBuilder() { // Arrange var manager = new ApplicationPartManager(); var builder = new MvcBuilder(Mock.Of(), manager); var assembly = typeof(MvcBuilder).GetTypeInfo().Assembly; // Act var result = builder.AddApplicationPart(assembly); // Assert Assert.Same(result, builder); var part = Assert.Single(builder.PartManager.ApplicationParts); var assemblyPart = Assert.IsType(part); Assert.Equal(assembly, assemblyPart.Assembly); } [Fact] public void ConfigureApplicationParts_InvokesSetupAction() { // Arrange var builder = new MvcBuilder( Mock.Of(), new ApplicationPartManager()); var part = new TestApplicationPart(); // Act var result = builder.ConfigureApplicationPartManager(manager => { manager.ApplicationParts.Add(part); }); // Assert Assert.Same(result, builder); Assert.Equal(new ApplicationPart[] { part }, builder.PartManager.ApplicationParts.ToArray()); } [Fact] public void WithControllersAsServices_AddsTypesToControllerTypeProviderAndServiceCollection() { // Arrange var collection = new ServiceCollection(); var controllerTypes = new[] { typeof(ControllerTypeA), typeof(TypeBController), }.Select(t => t.GetTypeInfo()).ToArray(); var builder = new MvcBuilder(collection, GetApplicationPartManager(controllerTypes)); // Act builder.AddControllersAsServices(); // Assert var services = collection.ToList(); Assert.Equal(3, services.Count); Assert.Equal(typeof(ControllerTypeA), services[0].ServiceType); Assert.Equal(typeof(ControllerTypeA), services[0].ImplementationType); Assert.Equal(ServiceLifetime.Transient, services[0].Lifetime); Assert.Equal(typeof(TypeBController), services[1].ServiceType); Assert.Equal(typeof(TypeBController), services[1].ImplementationType); Assert.Equal(ServiceLifetime.Transient, services[1].Lifetime); Assert.Equal(typeof(IControllerActivator), services[2].ServiceType); Assert.Equal(typeof(ServiceBasedControllerActivator), services[2].ImplementationType); Assert.Equal(ServiceLifetime.Transient, services[2].Lifetime); } [Fact] public void AddControllerAsServices_MultipleCalls_RetainsPreviouslyAddedTypes() { // Arrange var services = new ServiceCollection(); var manager = new ApplicationPartManager(); manager.ApplicationParts.Add(new TestApplicationPart(typeof(ControllerOne), typeof(ControllerTwo))); manager.FeatureProviders.Add(new TestFeatureProvider()); var builder = new MvcBuilder(services, manager); builder.AddControllersAsServices(); // Act builder.AddControllersAsServices(); // Assert 2 var collection = services.ToList(); Assert.Equal(3, collection.Count); Assert.Single(collection, d => d.ServiceType.Equals(typeof(ControllerOne))); Assert.Single(collection, d => d.ServiceType.Equals(typeof(ControllerTwo))); } private class ControllerOne { } private class ControllerTwo { } private static ApplicationPartManager GetApplicationPartManager(params TypeInfo[] types) { var manager = new ApplicationPartManager(); manager.ApplicationParts.Add(new TestApplicationPart(types)); manager.FeatureProviders.Add(new ControllerFeatureProvider()); return manager; } } } // These controllers are used to test the UseControllersAsServices implementation // which REQUIRES that they be public top-level classes. To avoid having to stub out the // implementation of this class to test it, they are just top level classes. Don't reuse // these outside this test - find a better way or use nested classes to keep the tests // independent. namespace Microsoft.AspNetCore.Mvc.MvcServiceCollectionExtensionsTestControllers { public class ControllerTypeA : Microsoft.AspNetCore.Mvc.Controller { } public class TypeBController { } }