[Fixes #4089] Add support for application parts
This commit introduces application parts as a concept on MVC. An application part is an abstraction that allows you to expose some feature or corncern in a way that is decoupled from their underlying source. Examples of this include types in an assembly, emdeded resources, files on disk etc. Application parts are configured during startup by adding or removing them from the application part manager available as part of IMvcBuilder and IMvcCoreBuilder. The application part manager provides the ability to populate features from the list of available application parts by using a list of application feature providers. Application feature providers are responsible for populating a given feature given a list of application parts. Examples of application providers can be a ControllerFeatureProvider that goes through the list of application parts, sees which one of those parts exposes types, determines which of those types are controller types, and adds them to a ControllerFeature that holds a list of all the types that will be considered controllers in the application.
This commit is contained in:
parent
7fbd407ad5
commit
1bd66ffda0
|
|
@ -0,0 +1,16 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ApplicationParts
|
||||
{
|
||||
/// <summary>
|
||||
/// A part of an MVC application.
|
||||
/// </summary>
|
||||
public abstract class ApplicationPart
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ApplicationPart"/> name.
|
||||
/// </summary>
|
||||
public abstract string Name { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ApplicationParts
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages the parts and features of an MVC application.
|
||||
/// </summary>
|
||||
public class ApplicationPartManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the list of <see cref="IApplicationFeatureProvider"/>s.
|
||||
/// </summary>
|
||||
public IList<IApplicationFeatureProvider> FeatureProviders { get; } =
|
||||
new List<IApplicationFeatureProvider>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of <see cref="ApplicationPart"/>s.
|
||||
/// </summary>
|
||||
public IList<ApplicationPart> ApplicationParts { get; } =
|
||||
new List<ApplicationPart>();
|
||||
|
||||
/// <summary>
|
||||
/// Populates the given <paramref name="feature"/> using the list of
|
||||
/// <see cref="IApplicationFeatureProvider{TFeature}"/>s configured on the
|
||||
/// <see cref="ApplicationPartManager"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TFeature">The type of the feature.</typeparam>
|
||||
/// <param name="feature">The feature instance to populate.</param>
|
||||
public void PopulateFeature<TFeature>(TFeature feature)
|
||||
{
|
||||
if (feature == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(feature));
|
||||
}
|
||||
|
||||
foreach (var provider in FeatureProviders.OfType<IApplicationFeatureProvider<TFeature>>())
|
||||
{
|
||||
provider.PopulateFeature(ApplicationParts, feature);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ApplicationParts
|
||||
{
|
||||
/// <summary>
|
||||
/// An <see cref="ApplicationPart"/> backed by an <see cref="Assembly"/>.
|
||||
/// </summary>
|
||||
public class AssemblyPart : ApplicationPart
|
||||
{
|
||||
/// <summary>
|
||||
/// Initalizes a new <see cref="AssemblyPart"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="assembly"></param>
|
||||
public AssemblyPart(Assembly assembly)
|
||||
{
|
||||
if (assembly == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(assembly));
|
||||
}
|
||||
|
||||
Assembly = assembly;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="Assembly"/> of the <see cref="ApplicationPart"/>.
|
||||
/// </summary>
|
||||
public Assembly Assembly { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the <see cref="ApplicationPart"/>.
|
||||
/// </summary>
|
||||
public override string Name => Assembly.GetName().Name;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ApplicationParts
|
||||
{
|
||||
/// <summary>
|
||||
/// Marker interface for <see cref="IApplicationFeatureProvider"/>
|
||||
/// implementations.
|
||||
/// </summary>
|
||||
public interface IApplicationFeatureProvider
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
// 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;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ApplicationParts
|
||||
{
|
||||
/// <summary>
|
||||
/// A provider for a given <typeparamref name="TFeature"/> feature.
|
||||
/// </summary>
|
||||
/// <typeparam name="TFeature">The type of the feature.</typeparam>
|
||||
public interface IApplicationFeatureProvider<TFeature> : IApplicationFeatureProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Updates the <paramref name="feature"/> intance.
|
||||
/// </summary>
|
||||
/// <param name="parts">The list of <see cref="ApplicationPart"/>s of the
|
||||
/// application.
|
||||
/// </param>
|
||||
/// <param name="feature">The feature instance to populate.</param>
|
||||
void PopulateFeature(IEnumerable<ApplicationPart> parts, TFeature feature);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
// 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 Microsoft.AspNetCore.Mvc.ApplicationParts;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
/// <summary>
|
||||
|
|
@ -12,5 +14,11 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
/// Gets the <see cref="IServiceCollection"/> where MVC services are configured.
|
||||
/// </summary>
|
||||
IServiceCollection Services { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ApplicationPartManager"/> where <see cref="ApplicationPart"/>s
|
||||
/// are configured.
|
||||
/// </summary>
|
||||
ApplicationPartManager PartManager { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
// 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 Microsoft.AspNetCore.Mvc.ApplicationParts;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
/// <summary>
|
||||
|
|
@ -12,5 +14,11 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
/// Gets the <see cref="IServiceCollection"/> where essential MVC services are configured.
|
||||
/// </summary>
|
||||
IServiceCollection Services { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ApplicationPartManager"/> where <see cref="ApplicationPart"/>s
|
||||
/// are configured.
|
||||
/// </summary>
|
||||
ApplicationPartManager PartManager { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,11 +3,12 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
|
||||
using Microsoft.AspNetCore.Mvc.Formatters;
|
||||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
|
|
@ -58,6 +59,56 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an <see cref="ApplicationPart"/> to the list of <see cref="ApplicationPartManager.ApplicationParts"/> on the
|
||||
/// <see cref="IMvcBuilder.PartManager"/>.
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="IMvcBuilder"/>.</param>
|
||||
/// <param name="assembly">The <see cref="Assembly"/> of the <see cref="ApplicationPart"/>.</param>
|
||||
/// <returns>The <see cref="IMvcBuilder"/>.</returns>
|
||||
public static IMvcBuilder AddApplicationPart(this IMvcBuilder builder, Assembly assembly)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
if (assembly == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(assembly));
|
||||
}
|
||||
|
||||
builder.ConfigureApplicationPartManager(manager => manager.ApplicationParts.Add(new AssemblyPart(assembly)));
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures the <see cref="ApplicationPartManager"/> of the <see cref="IMvcBuilder.PartManager"/> using
|
||||
/// the given <see cref="Action{ApplicationPartManager}"/>.
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="IMvcBuilder"/>.</param>
|
||||
/// <param name="setupAction">The <see cref="Action{ApplicationPartManager}"/></param>
|
||||
/// <returns>The <see cref="IMvcBuilder"/>.</returns>
|
||||
public static IMvcBuilder ConfigureApplicationPartManager(
|
||||
this IMvcBuilder builder,
|
||||
Action<ApplicationPartManager> setupAction)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
if (setupAction == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(setupAction));
|
||||
}
|
||||
|
||||
setupAction(builder.PartManager);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register the specified <paramref name="controllerTypes"/> as services and as a source for controller
|
||||
/// discovery.
|
||||
|
|
|
|||
|
|
@ -3,14 +3,15 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
|
||||
using Microsoft.AspNetCore.Mvc.Formatters;
|
||||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
|
|
@ -143,6 +144,56 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
return builder.AddControllersAsServices(controllerAssemblies.AsEnumerable());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an <see cref="ApplicationPart"/> to the list of <see cref="ApplicationPartManager.ApplicationParts"/> on the
|
||||
/// <see cref="IMvcCoreBuilder.PartManager"/>.
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="IMvcCoreBuilder"/>.</param>
|
||||
/// <param name="assembly">The <see cref="Assembly"/> of the <see cref="ApplicationPart"/>.</param>
|
||||
/// <returns>The <see cref="IMvcCoreBuilder"/>.</returns>
|
||||
public static IMvcCoreBuilder AddApplicationPart(this IMvcCoreBuilder builder, Assembly assembly)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
if (assembly == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(assembly));
|
||||
}
|
||||
|
||||
builder.ConfigureApplicationPartManager(manager => manager.ApplicationParts.Add(new AssemblyPart(assembly)));
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures the <see cref="ApplicationPartManager"/> of the <see cref="IMvcCoreBuilder.PartManager"/> using
|
||||
/// the given <see cref="Action{ApplicationPartManager}"/>.
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="IMvcCoreBuilder"/>.</param>
|
||||
/// <param name="setupAction">The <see cref="Action{ApplicationPartManager}"/></param>
|
||||
/// <returns>The <see cref="IMvcCoreBuilder"/>.</returns>
|
||||
public static IMvcCoreBuilder ConfigureApplicationPartManager(
|
||||
this IMvcCoreBuilder builder,
|
||||
Action<ApplicationPartManager> setupAction)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
if (setupAction == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(setupAction));
|
||||
}
|
||||
|
||||
setupAction(builder.PartManager);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers controller types from the specified <paramref name="controllerAssemblies"/> as services and as a source
|
||||
/// for controller discovery.
|
||||
|
|
|
|||
|
|
@ -3,10 +3,13 @@
|
|||
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Abstractions;
|
||||
using Microsoft.AspNetCore.Mvc.ActionConstraints;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||
|
|
@ -39,10 +42,45 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
throw new ArgumentNullException(nameof(services));
|
||||
}
|
||||
|
||||
var partManager = GetApplicationPartManager(services);
|
||||
services.TryAddSingleton(partManager);
|
||||
|
||||
ConfigureDefaultServices(services);
|
||||
AddMvcCoreServices(services);
|
||||
|
||||
return new MvcCoreBuilder(services);
|
||||
var builder = new MvcCoreBuilder(services, partManager);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
private static ApplicationPartManager GetApplicationPartManager(IServiceCollection services)
|
||||
{
|
||||
var manager = GetServiceFromCollection<ApplicationPartManager>(services);
|
||||
if (manager == null)
|
||||
{
|
||||
manager = new ApplicationPartManager();
|
||||
|
||||
var environment = GetServiceFromCollection<IHostingEnvironment>(services);
|
||||
if (environment == null)
|
||||
{
|
||||
return manager;
|
||||
}
|
||||
|
||||
var assemblies = new DefaultAssemblyProvider(environment).CandidateAssemblies;
|
||||
foreach (var assembly in assemblies)
|
||||
{
|
||||
manager.ApplicationParts.Add(new AssemblyPart(assembly));
|
||||
}
|
||||
}
|
||||
|
||||
return manager;
|
||||
}
|
||||
|
||||
private static T GetServiceFromCollection<T>(IServiceCollection services)
|
||||
{
|
||||
return (T)services
|
||||
.FirstOrDefault(d => d.ServiceType == typeof(T))
|
||||
?.ImplementationInstance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Internal
|
||||
|
|
@ -15,17 +16,27 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
|||
/// Initializes a new <see cref="MvcBuilder"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="services">The <see cref="IServiceCollection" /> to add services to.</param>
|
||||
public MvcBuilder(IServiceCollection services)
|
||||
/// <param name="manager">The <see cref="ApplicationPartManager"/> of the application.</param>
|
||||
public MvcBuilder(IServiceCollection services, ApplicationPartManager manager)
|
||||
{
|
||||
if (services == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(services));
|
||||
}
|
||||
|
||||
if (manager == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(manager));
|
||||
}
|
||||
|
||||
Services = services;
|
||||
PartManager = manager;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IServiceCollection Services { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ApplicationPartManager PartManager { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,9 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
|
||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Internal
|
||||
|
|
@ -12,19 +15,31 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
|||
public class MvcCoreBuilder : IMvcCoreBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="MvcCoreBuilder"/>.
|
||||
/// Initializes a new <see cref="MvcCoreBuilder"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="services">The <see cref="IServiceCollection" /> to add services to.</param>
|
||||
public MvcCoreBuilder(IServiceCollection services)
|
||||
/// <param name="manager">The <see cref="ApplicationPartManager"/> of the application.</param>
|
||||
public MvcCoreBuilder(
|
||||
IServiceCollection services,
|
||||
ApplicationPartManager manager)
|
||||
{
|
||||
if (services == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(services));
|
||||
}
|
||||
|
||||
if (manager == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(manager));
|
||||
}
|
||||
|
||||
Services = services;
|
||||
PartManager = manager;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ApplicationPartManager PartManager { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IServiceCollection Services { get; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,14 +16,21 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
|||
/// <summary>
|
||||
/// Sets up default options for <see cref="MvcOptions"/>.
|
||||
/// </summary>
|
||||
public class MvcCoreMvcOptionsSetup : ConfigureOptions<MvcOptions>
|
||||
public class MvcCoreMvcOptionsSetup : IConfigureOptions<MvcOptions>
|
||||
{
|
||||
private readonly IHttpRequestStreamReaderFactory _readerFactory;
|
||||
|
||||
public MvcCoreMvcOptionsSetup(IHttpRequestStreamReaderFactory readerFactory)
|
||||
: base((options) => ConfigureMvc(options, readerFactory))
|
||||
{
|
||||
if (readerFactory == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(readerFactory));
|
||||
}
|
||||
|
||||
_readerFactory = readerFactory;
|
||||
}
|
||||
|
||||
public static void ConfigureMvc(MvcOptions options, IHttpRequestStreamReaderFactory readerFactory)
|
||||
public void Configure(MvcOptions options)
|
||||
{
|
||||
// Set up default error messages
|
||||
var messageProvider = options.ModelBindingMessageProvider;
|
||||
|
|
@ -38,7 +45,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
|||
// Set up ModelBinding
|
||||
options.ModelBinderProviders.Add(new BinderTypeModelBinderProvider());
|
||||
options.ModelBinderProviders.Add(new ServicesModelBinderProvider());
|
||||
options.ModelBinderProviders.Add(new BodyModelBinderProvider(readerFactory));
|
||||
options.ModelBinderProviders.Add(new BodyModelBinderProvider(_readerFactory));
|
||||
options.ModelBinderProviders.Add(new HeaderModelBinderProvider());
|
||||
options.ModelBinderProviders.Add(new SimpleTypeModelBinderProvider());
|
||||
options.ModelBinderProviders.Add(new CancellationTokenModelBinderProvider());
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
|
||||
builder.AddCors();
|
||||
|
||||
return new MvcBuilder(builder.Services);
|
||||
return new MvcBuilder(builder.Services, builder.PartManager);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,150 @@
|
|||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ApplicationParts
|
||||
{
|
||||
public class ApplicationPartManagerTest
|
||||
{
|
||||
[Fact]
|
||||
public void PopulateFeature_InvokesAllProvidersSequentially_ForAGivenFeature()
|
||||
{
|
||||
// Arrange
|
||||
var manager = new ApplicationPartManager();
|
||||
manager.ApplicationParts.Add(new ControllersPart("ControllersPartA"));
|
||||
manager.ApplicationParts.Add(new ViewComponentsPart("ViewComponentsPartB"));
|
||||
manager.ApplicationParts.Add(new ControllersPart("ControllersPartC"));
|
||||
manager.FeatureProviders.Add(
|
||||
new ControllersFeatureProvider((f, v) => f.Values.Add($"ControllersFeatureProvider1{v}")));
|
||||
manager.FeatureProviders.Add(
|
||||
new ControllersFeatureProvider((f, v) => f.Values.Add($"ControllersFeatureProvider2{v}")));
|
||||
|
||||
var feature = new ControllersFeature();
|
||||
var expectedResults = new[] {
|
||||
"ControllersFeatureProvider1ControllersPartA",
|
||||
"ControllersFeatureProvider1ControllersPartC",
|
||||
"ControllersFeatureProvider2ControllersPartA",
|
||||
"ControllersFeatureProvider2ControllersPartC"
|
||||
};
|
||||
|
||||
// Act
|
||||
manager.PopulateFeature(feature);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedResults, feature.Values.ToArray());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PopulateFeature_InvokesOnlyProviders_ForAGivenFeature()
|
||||
{
|
||||
// Arrange
|
||||
var manager = new ApplicationPartManager();
|
||||
manager.ApplicationParts.Add(new ControllersPart("ControllersPart"));
|
||||
manager.FeatureProviders.Add(
|
||||
new ControllersFeatureProvider((f, v) => f.Values.Add($"ControllersFeatureProvider{v}")));
|
||||
manager.FeatureProviders.Add(
|
||||
new NotControllersedFeatureProvider((f, v) => f.Values.Add($"ViewComponentsFeatureProvider{v}")));
|
||||
|
||||
var feature = new ControllersFeature();
|
||||
var expectedResults = new[] { "ControllersFeatureProviderControllersPart" };
|
||||
|
||||
// Act
|
||||
manager.PopulateFeature(feature);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedResults, feature.Values.ToArray());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PopulateFeature_SkipProviders_ForOtherFeatures()
|
||||
{
|
||||
// Arrange
|
||||
var manager = new ApplicationPartManager();
|
||||
manager.ApplicationParts.Add(new ViewComponentsPart("ViewComponentsPart"));
|
||||
manager.FeatureProviders.Add(
|
||||
new ControllersFeatureProvider((f, v) => f.Values.Add($"ControllersFeatureProvider{v}")));
|
||||
|
||||
var feature = new ControllersFeature();
|
||||
|
||||
// Act
|
||||
manager.PopulateFeature(feature);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(feature.Values.ToArray());
|
||||
}
|
||||
|
||||
private class ControllersPart : ApplicationPart
|
||||
{
|
||||
public ControllersPart(string value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public override string Name => "Test";
|
||||
|
||||
public string Value { get; }
|
||||
}
|
||||
|
||||
private class ViewComponentsPart : ApplicationPart
|
||||
{
|
||||
public ViewComponentsPart(string value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public override string Name => "Other";
|
||||
|
||||
public string Value { get; }
|
||||
}
|
||||
|
||||
private class ControllersFeature
|
||||
{
|
||||
public IList<string> Values { get; } = new List<string>();
|
||||
}
|
||||
|
||||
private class ViewComponentsFeature
|
||||
{
|
||||
public IList<string> Values { get; } = new List<string>();
|
||||
}
|
||||
|
||||
private class NotControllersedFeatureProvider : IApplicationFeatureProvider<ViewComponentsFeature>
|
||||
{
|
||||
private readonly Action<ViewComponentsFeature, string> _operation;
|
||||
|
||||
public NotControllersedFeatureProvider(Action<ViewComponentsFeature, string> operation)
|
||||
{
|
||||
_operation = operation;
|
||||
}
|
||||
|
||||
public void PopulateFeature(IEnumerable<ApplicationPart> parts, ViewComponentsFeature feature)
|
||||
{
|
||||
foreach (var part in parts.OfType<ViewComponentsPart>())
|
||||
{
|
||||
_operation(feature, part.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ControllersFeatureProvider : IApplicationFeatureProvider<ControllersFeature>
|
||||
{
|
||||
private readonly Action<ControllersFeature, string> _operation;
|
||||
|
||||
public ControllersFeatureProvider(Action<ControllersFeature, string> operation)
|
||||
{
|
||||
_operation = operation;
|
||||
}
|
||||
|
||||
public void PopulateFeature(IEnumerable<ApplicationPart> parts, ControllersFeature feature)
|
||||
{
|
||||
foreach (var part in parts.OfType<ControllersPart>())
|
||||
{
|
||||
_operation(feature, part.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
// 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.Reflection;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.ApplicationParts
|
||||
{
|
||||
public class AssemblyPartTest
|
||||
{
|
||||
[Fact]
|
||||
public void AssemblyPart_Name_ReturnsAssemblyName()
|
||||
{
|
||||
// Arrange
|
||||
var part = new AssemblyPart(typeof(AssemblyPartTest).GetTypeInfo().Assembly);
|
||||
|
||||
// Act
|
||||
var name = part.Name;
|
||||
|
||||
// Assert
|
||||
Assert.Equal("Microsoft.AspNetCore.Mvc.Core.Test", name);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AssemblyPart_Assembly_ReturnsAssembly()
|
||||
{
|
||||
// Arrange
|
||||
var assembly = typeof(AssemblyPartTest).GetTypeInfo().Assembly;
|
||||
var part = new AssemblyPart(assembly);
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(part.Assembly, assembly);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,9 @@
|
|||
|
||||
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;
|
||||
|
|
@ -13,6 +15,46 @@ namespace Microsoft.AspNetCore.Mvc
|
|||
{
|
||||
public class MvcBuilderExtensionsTest
|
||||
{
|
||||
[Fact]
|
||||
public void AddApplicationPart_AddsAnApplicationPart_ToTheListOfPartsOnTheBuilder()
|
||||
{
|
||||
// Arrange
|
||||
var manager = new ApplicationPartManager();
|
||||
var builder = new MvcBuilder(Mock.Of<IServiceCollection>(), 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<AssemblyPart>(part);
|
||||
Assert.Equal(assembly, assemblyPart.Assembly);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConfigureApplicationParts_InvokesSetupAction()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new MvcBuilder(
|
||||
Mock.Of<IServiceCollection>(),
|
||||
new ApplicationPartManager());
|
||||
|
||||
var part = new TestPart();
|
||||
|
||||
// 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()
|
||||
{
|
||||
|
|
@ -50,6 +92,11 @@ namespace Microsoft.AspNetCore.Mvc
|
|||
Assert.Equal(controllerTypes, typeProvider.ControllerTypes.OrderBy(c => c.Name).Select(t => t.AsType()));
|
||||
Assert.Equal(ServiceLifetime.Singleton, services[3].Lifetime);
|
||||
}
|
||||
|
||||
private class TestPart : ApplicationPart
|
||||
{
|
||||
public override string Name => "Test";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
// 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.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
|
||||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.DependencyInjection
|
||||
{
|
||||
public class MvcCoreBuilderExtensionsTest
|
||||
{
|
||||
[Fact]
|
||||
public void AddApplicationPart_AddsAnApplicationPart_ToTheListOfPartsOnTheBuilder()
|
||||
{
|
||||
// Arrange
|
||||
var manager = new ApplicationPartManager();
|
||||
var builder = new MvcCoreBuilder(Mock.Of<IServiceCollection>(), manager);
|
||||
var assembly = typeof(MvcCoreBuilder).GetTypeInfo().Assembly;
|
||||
|
||||
// Act
|
||||
var result = builder.AddApplicationPart(assembly);
|
||||
|
||||
// Assert
|
||||
Assert.Same(result, builder);
|
||||
var part = Assert.Single(builder.PartManager.ApplicationParts);
|
||||
var assemblyPart = Assert.IsType<AssemblyPart>(part);
|
||||
Assert.Equal(assembly, assemblyPart.Assembly);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConfigureApplicationParts_InvokesSetupAction()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new MvcCoreBuilder(
|
||||
Mock.Of<IServiceCollection>(),
|
||||
new ApplicationPartManager());
|
||||
|
||||
var part = new TestPart();
|
||||
|
||||
// Act
|
||||
var result = builder.ConfigureApplicationPartManager(manager =>
|
||||
{
|
||||
manager.ApplicationParts.Add(part);
|
||||
});
|
||||
|
||||
// Assert
|
||||
Assert.Same(result, builder);
|
||||
Assert.Equal(new ApplicationPart[] { part }, builder.PartManager.ApplicationParts.ToArray());
|
||||
}
|
||||
|
||||
private class TestPart : ApplicationPart
|
||||
{
|
||||
public override string Name => "Test";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -362,7 +362,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
var bindingContext = CreateContext(GetMetadataForType(typeof(Person)), new Person());
|
||||
var originalModel = bindingContext.Model;
|
||||
|
||||
var binder = new Mock<TestableComplexTypeModelBinder>(){ CallBase = true };
|
||||
var binder = new Mock<TestableComplexTypeModelBinder>() { CallBase = true };
|
||||
binder
|
||||
.Setup(b => b.CreateModelPublic(It.IsAny<ModelBindingContext>()))
|
||||
.Verifiable();
|
||||
|
|
@ -1067,7 +1067,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
|
|||
private static TestableComplexTypeModelBinder CreateBinder(ModelMetadata metadata)
|
||||
{
|
||||
var options = new TestOptionsManager<MvcOptions>();
|
||||
MvcCoreMvcOptionsSetup.ConfigureMvc(options.Value, new TestHttpRequestStreamReaderFactory());
|
||||
var setup = new MvcCoreMvcOptionsSetup(new TestHttpRequestStreamReaderFactory());
|
||||
setup.Configure(options.Value);
|
||||
|
||||
var lastIndex = options.Value.ModelBinderProviders.Count - 1;
|
||||
Assert.IsType<ComplexTypeModelBinderProvider>(options.Value.ModelBinderProviders[lastIndex]);
|
||||
|
|
|
|||
|
|
@ -2,10 +2,13 @@
|
|||
// 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.IO;
|
||||
using System.Net.Http;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||
using Microsoft.AspNetCore.Mvc.Razor.Compilation;
|
||||
using Microsoft.AspNetCore.Mvc.Razor.Internal;
|
||||
|
|
@ -68,6 +71,17 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
var assemblyProvider = new StaticAssemblyProvider();
|
||||
assemblyProvider.CandidateAssemblies.Add(startupAssembly);
|
||||
services.AddSingleton<IAssemblyProvider>(assemblyProvider);
|
||||
|
||||
var manager = new ApplicationPartManager();
|
||||
manager.ApplicationParts.Add(new AssemblyPart(startupAssembly));
|
||||
services.AddSingleton(manager);
|
||||
}
|
||||
|
||||
private class StaticAssemblyProvider : IAssemblyProvider
|
||||
{
|
||||
public IList<Assembly> CandidateAssemblies { get; } = new List<Assembly>();
|
||||
|
||||
IEnumerable<Assembly> IAssemblyProvider.CandidateAssemblies => CandidateAssemblies;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
|
|
@ -99,6 +100,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
|
|||
private static IServiceProvider GetServices(Action<MvcOptions> updateOptions = null)
|
||||
{
|
||||
var serviceCollection = new ServiceCollection();
|
||||
serviceCollection.AddSingleton(new ApplicationPartManager());
|
||||
serviceCollection.AddMvc();
|
||||
serviceCollection
|
||||
.AddSingleton<ObjectPoolProvider, DefaultObjectPoolProvider>()
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System.Buffers;
|
|||
using Microsoft.AspNetCore.Mvc.DataAnnotations;
|
||||
using Microsoft.AspNetCore.Mvc.DataAnnotations.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.Formatters.Json.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
|
||||
|
|
@ -20,7 +21,9 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
|
|||
public TestMvcOptions()
|
||||
{
|
||||
Value = new MvcOptions();
|
||||
MvcCoreMvcOptionsSetup.ConfigureMvc(Value, new TestHttpRequestStreamReaderFactory());
|
||||
var optionsSetup = new MvcCoreMvcOptionsSetup(new TestHttpRequestStreamReaderFactory());
|
||||
optionsSetup.Configure(Value);
|
||||
|
||||
var collection = new ServiceCollection().AddOptions();
|
||||
collection.AddSingleton<ICompositeMetadataDetailsProvider, DefaultCompositeMetadataDetailsProvider>();
|
||||
collection.AddSingleton<IModelMetadataProvider, DefaultModelMetadataProvider>();
|
||||
|
|
|
|||
|
|
@ -2,8 +2,11 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Abstractions;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
|
||||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.Abstractions;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
|
||||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
|
|
@ -28,7 +28,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
|||
{
|
||||
// Arrange
|
||||
var services = new ServiceCollection();
|
||||
var builder = new MvcCoreBuilder(services);
|
||||
var builder = new MvcCoreBuilder(services, new ApplicationPartManager());
|
||||
builder.InitializeTagHelper<TestTagHelper>((h, vc) =>
|
||||
{
|
||||
h.Name = name;
|
||||
|
|
@ -55,7 +55,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
|||
{
|
||||
// Arrange
|
||||
var services = new ServiceCollection();
|
||||
var builder = new MvcCoreBuilder(services);
|
||||
var builder = new MvcCoreBuilder(services, new ApplicationPartManager());
|
||||
builder.InitializeTagHelper<TestTagHelper>((h, _) => h.ViewContext = MakeViewContext(MakeHttpContext()));
|
||||
var httpContext = MakeHttpContext(services.BuildServiceProvider());
|
||||
var viewContext = MakeViewContext(httpContext);
|
||||
|
|
@ -73,7 +73,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
|||
{
|
||||
// Arrange
|
||||
var services = new ServiceCollection();
|
||||
var builder = new MvcCoreBuilder(services);
|
||||
var builder = new MvcCoreBuilder(services, new ApplicationPartManager());
|
||||
builder.InitializeTagHelper<TestTagHelper>((h, vc) =>
|
||||
{
|
||||
h.Name = "Test 1";
|
||||
|
|
@ -101,7 +101,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
|||
{
|
||||
// Arrange
|
||||
var services = new ServiceCollection();
|
||||
var builder = new MvcCoreBuilder(services);
|
||||
var builder = new MvcCoreBuilder(services, new ApplicationPartManager());
|
||||
builder.InitializeTagHelper<TestTagHelper>((h, vc) =>
|
||||
{
|
||||
h.Name = "Test 1";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// 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 Microsoft.AspNetCore.Mvc.ApplicationParts;
|
||||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
|
@ -18,7 +19,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
|
|||
var fileProvider = new TestFileProvider();
|
||||
|
||||
// Act
|
||||
var builder = new MvcBuilder(services);
|
||||
var builder = new MvcBuilder(services, new ApplicationPartManager());
|
||||
builder.AddRazorOptions(options =>
|
||||
{
|
||||
options.FileProviders.Add(fileProvider);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ using System.Xml;
|
|||
using System.Xml.Linq;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
|
||||
using Microsoft.AspNetCore.Mvc.DataAnnotations.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.Formatters;
|
||||
using Microsoft.AspNetCore.Mvc.Internal;
|
||||
|
|
@ -148,7 +149,7 @@ namespace Microsoft.AspNetCore.Mvc
|
|||
// Arrange & Act
|
||||
var options = GetOptions<MvcOptions>(services =>
|
||||
{
|
||||
var builder = new MvcCoreBuilder(services);
|
||||
var builder = new MvcCoreBuilder(services, new ApplicationPartManager());
|
||||
builder.AddXmlDataContractSerializerFormatters();
|
||||
});
|
||||
|
||||
|
|
@ -238,6 +239,7 @@ namespace Microsoft.AspNetCore.Mvc
|
|||
private static IServiceProvider GetServiceProvider(Action<IServiceCollection> action = null)
|
||||
{
|
||||
var serviceCollection = new ServiceCollection();
|
||||
serviceCollection.AddSingleton(new ApplicationPartManager());
|
||||
serviceCollection.AddMvc();
|
||||
serviceCollection
|
||||
.AddSingleton<ObjectPoolProvider, DefaultObjectPoolProvider>()
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc.Abstractions;
|
||||
using Microsoft.AspNetCore.Mvc.ActionConstraints;
|
||||
using Microsoft.AspNetCore.Mvc.ApiExplorer;
|
||||
|
|
@ -41,6 +42,7 @@ namespace Microsoft.AspNetCore.Mvc
|
|||
{
|
||||
// Arrange
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton<IHostingEnvironment>(GetHostingEnvironment());
|
||||
|
||||
// Register a mock implementation of each service, AddMvcServices should add another implemenetation.
|
||||
foreach (var serviceType in MutliRegistrationServiceTypes)
|
||||
|
|
@ -69,6 +71,7 @@ namespace Microsoft.AspNetCore.Mvc
|
|||
{
|
||||
// Arrange
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton<IHostingEnvironment>(GetHostingEnvironment());
|
||||
|
||||
// Register a mock implementation of each service, AddMvcServices should not replace it.
|
||||
foreach (var serviceType in SingleRegistrationServiceTypes)
|
||||
|
|
@ -92,6 +95,7 @@ namespace Microsoft.AspNetCore.Mvc
|
|||
{
|
||||
// Arrange
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton<IHostingEnvironment>(GetHostingEnvironment());
|
||||
|
||||
// Act
|
||||
services.AddMvc();
|
||||
|
|
@ -123,6 +127,7 @@ namespace Microsoft.AspNetCore.Mvc
|
|||
get
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton<IHostingEnvironment>(GetHostingEnvironment());
|
||||
services.AddMvc();
|
||||
|
||||
var multiRegistrationServiceTypes = MutliRegistrationServiceTypes;
|
||||
|
|
@ -266,5 +271,15 @@ namespace Microsoft.AspNetCore.Mvc
|
|||
$"Found multiple instances of {implementationType} registered as {serviceType}");
|
||||
}
|
||||
}
|
||||
|
||||
private IHostingEnvironment GetHostingEnvironment()
|
||||
{
|
||||
var environment = new Mock<IHostingEnvironment>();
|
||||
environment
|
||||
.Setup(e => e.ApplicationName)
|
||||
.Returns(typeof(MvcServiceCollectionExtensionsTest).GetTypeInfo().Assembly.GetName().Name);
|
||||
|
||||
return environment.Object;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue