Removing MvcViewEngineDescriptor and switching to use OptionsSetup to

setup RazorViewEngine.

Fixes #2269
This commit is contained in:
Pranav K 2015-07-29 08:19:45 -07:00
parent bb158ec6ee
commit 7120b2ff92
14 changed files with 82 additions and 580 deletions

View File

@ -52,6 +52,8 @@ namespace Microsoft.Framework.DependencyInjection
services.TryAddEnumerable(
ServiceDescriptor.Transient<IConfigureOptions<RazorViewEngineOptions>, RazorViewEngineOptionsSetup>());
services.TryAddSingleton<IRazorViewEngine, RazorViewEngine>();
// Caches view locations that are valid for the lifetime of the application.
services.TryAddSingleton<IViewLocationCache, DefaultViewLocationCache>();
services.TryAdd(ServiceDescriptor.Singleton<IChunkTreeCache>(serviceProvider =>

View File

@ -1,21 +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 Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.Internal;
using Microsoft.Framework.OptionsModel;
namespace Microsoft.AspNet.Mvc.Razor
{
/// <summary>
/// Configures <see cref="MvcViewOptions"/> to use <see cref="RazorViewEngine"/>.
/// </summary>
public class MvcRazorMvcViewOptionsSetup : ConfigureOptions<MvcViewOptions>
{
public MvcRazorMvcViewOptionsSetup()
: base(ConfigureMvc)
/// <summary>
/// Initializes a new instance of <see cref="MvcRazorMvcViewOptionsSetup"/>.
/// </summary>
/// <param name="serviceProvider">The application's <see cref="IServiceProvider"/>.</param>
public MvcRazorMvcViewOptionsSetup(IServiceProvider serviceProvider)
: base(options => ConfigureMvc(serviceProvider, options))
{
Order = DefaultOrder.DefaultFrameworkSortOrder;
}
public static void ConfigureMvc(MvcViewOptions options)
/// <summary>
/// Configures <paramref name="options"/> to use <see cref="RazorViewEngine"/>.
/// </summary>
/// <param name="serviceProvider">The application's <see cref="IServiceProvider"/>.</param>
/// <param name="options">The <see cref="MvcViewOptions"/> to configure.</param>
public static void ConfigureMvc(
[NotNull] IServiceProvider serviceProvider,
[NotNull] MvcViewOptions options)
{
options.ViewEngines.Add(typeof(RazorViewEngine));
var razorViewEngine = serviceProvider.GetRequiredService<IRazorViewEngine>();
options.ViewEngines.Add(razorViewEngine);
}
}
}

View File

@ -55,9 +55,7 @@ namespace Microsoft.Framework.DependencyInjection
//
// View Engine and related infrastructure
//
// The provider is inexpensive to initialize and provides ViewEngines that may require request
// specific services.
services.TryAddScoped<ICompositeViewEngine, CompositeViewEngine>();
services.TryAddSingleton<ICompositeViewEngine, CompositeViewEngine>();
// Support for activating ViewDataDictionary
services.TryAddEnumerable(

View File

@ -19,10 +19,9 @@ namespace Microsoft.AspNet.Mvc
public HtmlHelperOptions HtmlHelperOptions { get;[param: NotNull] set; } = new HtmlHelperOptions();
/// <summary>
/// Gets a list of descriptors that represent <see cref="Rendering.IViewEngine"/> used
/// by this application.
/// Gets a list <see cref="IViewEngine"/>s used by this application.
/// </summary>
public IList<ViewEngineDescriptor> ViewEngines { get; } = new List<ViewEngineDescriptor>();
public IList<IViewEngine> ViewEngines { get; } = new List<IViewEngine>();
/// <summary>
/// Gets a list of <see cref="IClientModelValidatorProvider"/> instances.

View File

@ -7,10 +7,13 @@ using Microsoft.Framework.OptionsModel;
namespace Microsoft.AspNet.Mvc
{
/// <summary>
/// Sets up default options for <see cref="MvcOptions"/>.
/// Sets up default options for <see cref="MvcViewOptions"/>.
/// </summary>
public class MvcViewOptionsSetup : ConfigureOptions<MvcViewOptions>
{
/// <summary>
/// Initializes a new instance of <see cref="MvcViewOptionsSetup"/>.
/// </summary>
public MvcViewOptionsSetup()
: base(ConfigureMvc)
{

View File

@ -1,7 +1,6 @@
// 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 Microsoft.Framework.Internal;
@ -15,41 +14,14 @@ namespace Microsoft.AspNet.Mvc.Rendering
/// <summary>
/// Initializes a new instance of <see cref="CompositeViewEngine"/>.
/// </summary>
/// <param name="optionsAccessor">The options accessor for <see cref="MvcOptions"/>.</param>
/// <param name="typeActivatorCache">As <see cref="ITypeActivatorCache"/> instance that creates
/// an instance of type <see cref="IViewEngine"/>.</param>
/// <param name="serviceProvider">A <see cref="IServiceProvider"/> instance that retrieves services from the
/// service collection.</param>
public CompositeViewEngine(
IOptions<MvcViewOptions> optionsAccessor,
ITypeActivatorCache typeActivatorCache,
IServiceProvider serviceProvider)
/// <param name="optionsAccessor">The options accessor for <see cref="MvcViewOptions"/>.</param>
public CompositeViewEngine(IOptions<MvcViewOptions> optionsAccessor)
{
var viewEngines = new List<IViewEngine>();
foreach (var descriptor in optionsAccessor.Options.ViewEngines)
{
IViewEngine viewEngine;
if (descriptor.ViewEngine != null)
{
viewEngine = descriptor.ViewEngine;
}
else
{
viewEngine = typeActivatorCache.CreateInstance<IViewEngine>(
serviceProvider,
descriptor.ViewEngineType);
}
viewEngines.Add(viewEngine);
}
ViewEngines = viewEngines;
ViewEngines = optionsAccessor.Options.ViewEngines.ToArray();
}
/// <summary>
/// Gets the list of <see cref="IViewEngine"/> this instance of <see cref="CompositeViewEngine"/> delegates to.
/// </summary>
public IReadOnlyList<IViewEngine> ViewEngines { get; }
/// <inheritdoc />
public IReadOnlyList<IViewEngine> ViewEngines { get; }
/// <inheritdoc />
public ViewEngineResult FindPartialView([NotNull] ActionContext context,

View File

@ -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 System.Collections.Generic;
namespace Microsoft.AspNet.Mvc.Rendering
{
/// <summary>
@ -8,5 +10,10 @@ namespace Microsoft.AspNet.Mvc.Rendering
/// </summary>
public interface ICompositeViewEngine : IViewEngine
{
/// <summary>
/// Gets the list of <see cref="IViewEngine"/> this instance of <see cref="ICompositeViewEngine"/> delegates
/// to.
/// </summary>
IReadOnlyList<IViewEngine> ViewEngines { get; }
}
}

View File

@ -1,52 +0,0 @@
// 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.Reflection;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Mvc.ViewFeatures;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Mvc
{
/// <summary>
/// Encapsulates information that describes an <see cref="IViewEngine"/>.
/// </summary>
public class ViewEngineDescriptor
{
/// <summary>
/// Creates a new instance of <see cref="ViewEngineDescriptor"/>.
/// </summary>
/// <param name="type">The <see cref="IViewEngine"/> type that the descriptor represents.</param>
public ViewEngineDescriptor([NotNull] Type type)
{
if (!typeof(IViewEngine).GetTypeInfo().IsAssignableFrom(type.GetTypeInfo()))
{
var message = Resources.FormatTypeMustDeriveFromType(type.FullName, typeof(IViewEngine).FullName);
throw new ArgumentException(message, nameof(type));
}
ViewEngineType = type;
}
/// <summary>
/// Creates a new instance of <see cref="ViewEngineDescriptor"/> using the specified type.
/// </summary>
/// <param name="viewEngine">An instance of <see cref="IViewEngine"/> that the descriptor represents.</param>
public ViewEngineDescriptor([NotNull] IViewEngine viewEngine)
{
ViewEngine = viewEngine;
ViewEngineType = viewEngine.GetType();
}
/// <summary>
/// Gets the type of the <see cref="IViewEngine"/> described by this <see cref="ViewEngineDescriptor"/>.
/// </summary>
public Type ViewEngineType { get; }
/// <summary>
/// Gets the <see cref="IViewEngine"/> instance described by this <see cref="ViewEngineDescriptor"/>.
/// </summary>
public IViewEngine ViewEngine { get; }
}
}

View File

@ -1,140 +0,0 @@
// 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 Microsoft.AspNet.Mvc.Rendering;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Mvc
{
/// <summary>
/// Extension methods for adding view engines to a descriptor collection.
/// </summary>
public static class ViewEngineDescriptorExtensions
{
/// <summary>
/// Adds a type representing a <see cref="IViewEngine"/> to a descriptor collection.
/// </summary>
/// <param name="descriptors">A list of ViewEngineDescriptors</param>
/// <param name="viewEngineType">Type representing an <see cref="IViewEngine"/>.</param>
/// <returns>ViewEngineDescriptor representing the added instance.</returns>
public static ViewEngineDescriptor Add(
[NotNull] this IList<ViewEngineDescriptor> descriptors,
[NotNull] Type viewEngineType)
{
var descriptor = new ViewEngineDescriptor(viewEngineType);
descriptors.Add(descriptor);
return descriptor;
}
/// <summary>
/// Inserts a type representing a <see cref="IViewEngine"/> to a descriptor collection.
/// </summary>
/// <param name="descriptors">A list of ViewEngineDescriptors</param>
/// <param name="viewEngineType">Type representing an <see cref="IViewEngine"/>.</param>
/// <returns>ViewEngineDescriptor representing the inserted instance.</returns>
public static ViewEngineDescriptor Insert(
[NotNull] this IList<ViewEngineDescriptor> descriptors,
int index,
[NotNull] Type viewEngineType)
{
if (index < 0 || index > descriptors.Count)
{
throw new ArgumentOutOfRangeException(nameof(index));
}
var descriptor = new ViewEngineDescriptor(viewEngineType);
descriptors.Insert(index, descriptor);
return descriptor;
}
/// <summary>
/// Adds an <see cref="IViewEngine"/> to a descriptor collection.
/// </summary>
/// <param name="descriptors">A list of ViewEngineDescriptors</param>
/// <param name="viewEngine">An <see cref="IViewEngine"/> instance.</param>
/// <returns>ViewEngineDescriptor representing the added instance.</returns>
public static ViewEngineDescriptor Add(
[NotNull] this IList<ViewEngineDescriptor> descriptors,
[NotNull] IViewEngine viewEngine)
{
var descriptor = new ViewEngineDescriptor(viewEngine);
descriptors.Add(descriptor);
return descriptor;
}
/// <summary>
/// Insert an <see cref="IViewEngine"/> to a descriptor collection.
/// </summary>
/// <param name="descriptors">A list of ViewEngineDescriptors</param>
/// <param name="viewEngine">An <see cref="IViewEngine"/> instance.</param>
/// <returns>ViewEngineDescriptor representing the added instance.</returns>
public static ViewEngineDescriptor Insert(
[NotNull] this IList<ViewEngineDescriptor> descriptors,
int index,
[NotNull] IViewEngine viewEngine)
{
if (index < 0 || index > descriptors.Count)
{
throw new ArgumentOutOfRangeException(nameof(index));
}
var descriptor = new ViewEngineDescriptor(viewEngine);
descriptors.Insert(index, descriptor);
return descriptor;
}
/// <summary>
/// Returns the only instance of <typeparamref name="TInstance"/> from <paramref name="descriptors" />.
/// </summary>
/// <typeparam name="TInstance">The type of the instance to find.</typeparam>
/// <param name="descriptors">The <see cref="IList{ViewEngineDescriptor}"/> to search.</param>
/// <returns>The only instance of <typeparamref name="TInstance"/> in <paramref name="descriptors"/>.</returns>
/// <exception cref="InvalidOperationException">
/// Thrown if there is not exactly one <typeparamref name="TInstance"/> in <paramref name="descriptors" />.
/// </exception>
public static TInstance InstanceOf<TInstance>(
[NotNull] this IList<ViewEngineDescriptor> descriptors)
{
return descriptors
.Select(descriptor => descriptor.ViewEngine)
.OfType<TInstance>()
.Single();
}
/// <summary>
/// Returns the only instance of <typeparamref name="TInstance"/> from <paramref name="descriptors" />
/// or <c>null</c> if the sequence is empty.
/// </summary>
/// <typeparam name="TInstance">The type of the instance to find.</typeparam>
/// <param name="descriptors">The <see cref="IList{ViewEngineDescriptor}"/> to search.</param>
/// <exception cref="InvalidOperationException">
/// Thrown if there is more than one <typeparamref name="TInstance"/> in <paramref name="descriptors" />.
/// </exception>
public static TInstance InstanceOfOrDefault<TInstance>(
[NotNull] this IList<ViewEngineDescriptor> descriptors)
{
return descriptors
.Select(descriptor => descriptor.ViewEngine)
.OfType<TInstance>()
.SingleOrDefault();
}
/// <summary>
/// Returns all instances of <typeparamref name="TInstance"/> from <paramref name="descriptors" />.
/// </summary>
/// <typeparam name="TInstance">The type of the instances to find.</typeparam>
/// <param name="descriptors">The <see cref="IList{ViewEngineDescriptor}"/> to search.</param>
/// <returns>An IEnumerable of <typeparamref name="TInstance"/> that contains instances from
/// <paramref name="descriptors"/>.</returns>
public static IEnumerable<TInstance> InstancesOf<TInstance>(
[NotNull] this IList<ViewEngineDescriptor> descriptors)
{
return descriptors
.Select(descriptor => descriptor.ViewEngine)
.OfType<TInstance>();
}
}
}

View File

@ -2,13 +2,16 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.ModelBinding.Validation;
using Microsoft.AspNet.Mvc.Razor;
using Microsoft.Dnx.Runtime;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.OptionsModel;
using Moq;
using Newtonsoft.Json.Linq;
using Xunit;
@ -20,11 +23,11 @@ namespace Microsoft.AspNet.Mvc
public void Setup_SetsUpViewEngines()
{
// Arrange & Act
var options = GetOptions<MvcViewOptions>();
var options = GetOptions<MvcViewOptions>(AddDnxServices);
// Assert
Assert.Equal(1, options.ViewEngines.Count);
Assert.Equal(typeof(RazorViewEngine), options.ViewEngines[0].ViewEngineType);
var viewEngine = Assert.Single(options.ViewEngines);
Assert.IsType<RazorViewEngine>(viewEngine);
}
[Fact]
@ -107,7 +110,7 @@ namespace Microsoft.AspNet.Mvc
public void Setup_SetsUpClientModelValidatorProviders()
{
// Arrange & Act
var options = GetOptions<MvcViewOptions>();
var options = GetOptions<MvcViewOptions>(AddDnxServices);
// Assert
Assert.Equal(2, options.ClientModelValidatorProviders.Count);
@ -220,5 +223,19 @@ namespace Microsoft.AspNet.Mvc
var serviceProvider = serviceCollection.BuildServiceProvider();
return serviceProvider;
}
private static void AddDnxServices(IServiceCollection serviceCollection)
{
serviceCollection.AddInstance(Mock.Of<ILibraryManager>());
serviceCollection.AddInstance(Mock.Of<IAssemblyLoadContextAccessor>());
var applicationEnvironment = new Mock<IApplicationEnvironment>();
// ApplicationBasePath is used to set up a PhysicalFileProvider which requires
// a real directory.
applicationEnvironment.SetupGet(e => e.ApplicationBasePath)
.Returns(Directory.GetCurrentDirectory());
serviceCollection.AddInstance(applicationEnvironment.Object);
}
}
}

View File

@ -13,35 +13,21 @@ namespace Microsoft.AspNet.Mvc.Rendering
public class CompositeViewEngineTest
{
[Fact]
public void ViewEngines_ReturnsInstantiatedListOfViewEngines()
public void ViewEngines_UsesListOfViewEnginesFromOptions()
{
// Arrange
var service = Mock.Of<ITestService>();
var viewEngine = Mock.Of<IViewEngine>();
var type = typeof(TestViewEngine);
var serviceProvider = new Mock<IServiceProvider>();
serviceProvider.Setup(p => p.GetService(typeof(ITestService)))
.Returns(service);
var typeActivatorCache = new DefaultTypeActivatorCache();
var viewEngine1 = Mock.Of<IViewEngine>();
var viewEngine2 = Mock.Of<IViewEngine>();
var optionsAccessor = new MockMvcViewOptionsAccessor();
optionsAccessor.Options.ViewEngines.Add(viewEngine);
optionsAccessor.Options.ViewEngines.Add(type);
var compositeViewEngine = new CompositeViewEngine(
optionsAccessor,
typeActivatorCache,
serviceProvider.Object);
optionsAccessor.Options.ViewEngines.Add(viewEngine1);
optionsAccessor.Options.ViewEngines.Add(viewEngine2);
var compositeViewEngine = new CompositeViewEngine(optionsAccessor);
// Act
var result = compositeViewEngine.ViewEngines;
// Assert
Assert.Collection(result,
actual => Assert.Same(viewEngine, actual),
actual =>
{
var testViewEngine = Assert.IsType<TestViewEngine>(actual);
Assert.Same(service, testViewEngine.Service);
});
Assert.Equal(new[] { viewEngine1, viewEngine2 }, result);
}
[Fact]
@ -51,10 +37,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
var viewName = "test-view";
var actionContext = GetActionContext();
var optionsAccessor = new MockMvcViewOptionsAccessor();
var compositeViewEngine = new CompositeViewEngine(
optionsAccessor,
Mock.Of<ITypeActivatorCache>(),
Mock.Of<IServiceProvider>());
var compositeViewEngine = new CompositeViewEngine(optionsAccessor);
// Act
var result = compositeViewEngine.FindView(actionContext, viewName);
@ -75,10 +58,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
.Returns(ViewEngineResult.NotFound(viewName, new[] { "controller/test-view" }));
var optionsAccessor = new MockMvcViewOptionsAccessor();
optionsAccessor.Options.ViewEngines.Add(engine.Object);
var compositeViewEngine = new CompositeViewEngine(
optionsAccessor,
Mock.Of<ITypeActivatorCache>(),
Mock.Of<IServiceProvider>());
var compositeViewEngine = new CompositeViewEngine(optionsAccessor);
// Act
var result = compositeViewEngine.FindView(GetActionContext(), viewName);
@ -99,10 +79,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
.Returns(ViewEngineResult.Found(viewName, view));
var optionsAccessor = new MockMvcViewOptionsAccessor();
optionsAccessor.Options.ViewEngines.Add(engine.Object);
var compositeViewEngine = new CompositeViewEngine(
optionsAccessor,
Mock.Of<ITypeActivatorCache>(),
Mock.Of<IServiceProvider>());
var compositeViewEngine = new CompositeViewEngine(optionsAccessor);
// Act
var result = compositeViewEngine.FindView(GetActionContext(), viewName);
@ -133,10 +110,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
optionsAccessor.Options.ViewEngines.Add(engine1.Object);
optionsAccessor.Options.ViewEngines.Add(engine2.Object);
optionsAccessor.Options.ViewEngines.Add(engine3.Object);
var compositeViewEngine = new CompositeViewEngine(
optionsAccessor,
Mock.Of<ITypeActivatorCache>(),
Mock.Of<IServiceProvider>());
var compositeViewEngine = new CompositeViewEngine(optionsAccessor);
// Act
var result = compositeViewEngine.FindView(GetActionContext(), viewName);
@ -166,10 +140,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
optionsAccessor.Options.ViewEngines.Add(engine1.Object);
optionsAccessor.Options.ViewEngines.Add(engine2.Object);
optionsAccessor.Options.ViewEngines.Add(engine3.Object);
var compositeViewEngine = new CompositeViewEngine(
optionsAccessor,
Mock.Of<ITypeActivatorCache>(),
Mock.Of<IServiceProvider>());
var compositeViewEngine = new CompositeViewEngine(optionsAccessor);
// Act
var result = compositeViewEngine.FindView(GetActionContext(), viewName);
@ -185,10 +156,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
// Arrange
var viewName = "my-partial-view";
var optionsAccessor = new MockMvcViewOptionsAccessor();
var compositeViewEngine = new CompositeViewEngine(
optionsAccessor,
Mock.Of<ITypeActivatorCache>(),
Mock.Of<IServiceProvider>());
var compositeViewEngine = new CompositeViewEngine(optionsAccessor);
// Act
var result = compositeViewEngine.FindPartialView(GetActionContext(), viewName);
@ -208,10 +176,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
.Returns(ViewEngineResult.NotFound(viewName, new[] { "Shared/partial-view" }));
var optionsAccessor = new MockMvcViewOptionsAccessor();
optionsAccessor.Options.ViewEngines.Add(engine.Object);
var compositeViewEngine = new CompositeViewEngine(
optionsAccessor,
Mock.Of<ITypeActivatorCache>(),
Mock.Of<IServiceProvider>());
var compositeViewEngine = new CompositeViewEngine(optionsAccessor);
// Act
var result = compositeViewEngine.FindPartialView(GetActionContext(), viewName);
@ -232,10 +197,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
.Returns(ViewEngineResult.Found(viewName, view));
var optionsAccessor = new MockMvcViewOptionsAccessor();
optionsAccessor.Options.ViewEngines.Add(engine.Object);
var compositeViewEngine = new CompositeViewEngine(
optionsAccessor,
Mock.Of<ITypeActivatorCache>(),
Mock.Of<IServiceProvider>());
var compositeViewEngine = new CompositeViewEngine(optionsAccessor);
// Act
var result = compositeViewEngine.FindPartialView(GetActionContext(), viewName);
@ -266,10 +228,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
optionsAccessor.Options.ViewEngines.Add(engine1.Object);
optionsAccessor.Options.ViewEngines.Add(engine2.Object);
optionsAccessor.Options.ViewEngines.Add(engine3.Object);
var compositeViewEngine = new CompositeViewEngine(
optionsAccessor,
Mock.Of<ITypeActivatorCache>(),
Mock.Of<IServiceProvider>());
var compositeViewEngine = new CompositeViewEngine(optionsAccessor);
// Act
var result = compositeViewEngine.FindPartialView(GetActionContext(), viewName);
@ -299,10 +258,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
optionsAccessor.Options.ViewEngines.Add(engine1.Object);
optionsAccessor.Options.ViewEngines.Add(engine2.Object);
optionsAccessor.Options.ViewEngines.Add(engine3.Object);
var compositeViewEngine = new CompositeViewEngine(
optionsAccessor,
Mock.Of<ITypeActivatorCache>(),
Mock.Of<IServiceProvider>());
var compositeViewEngine = new CompositeViewEngine(optionsAccessor);
// Act
var result = compositeViewEngine.FindPartialView(GetActionContext(), viewName);

View File

@ -1,210 +0,0 @@
// 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 Microsoft.AspNet.Mvc.Rendering;
using Moq;
using Xunit;
namespace Microsoft.AspNet.Mvc
{
public class ViewEngineDescriptorExtensionsTest
{
[Theory]
[InlineData(-1)]
[InlineData(5)]
public void Insert_WithType_ThrowsIfIndexIsOutOfBounds(int index)
{
// Arrange
var collection = new List<ViewEngineDescriptor>
{
new ViewEngineDescriptor(Mock.Of<IViewEngine>()),
new ViewEngineDescriptor(Mock.Of<IViewEngine>())
};
// Act & Assert
Assert.Throws<ArgumentOutOfRangeException>("index", () => collection.Insert(index, typeof(IViewEngine)));
}
[Theory]
[InlineData(-2)]
[InlineData(3)]
public void Insert_WithInstance_ThrowsIfIndexIsOutOfBounds(int index)
{
// Arrange
var collection = new List<ViewEngineDescriptor>
{
new ViewEngineDescriptor(Mock.Of<IViewEngine>()),
new ViewEngineDescriptor(Mock.Of<IViewEngine>())
};
var viewEngine = Mock.Of<IViewEngine>();
// Act & Assert
Assert.Throws<ArgumentOutOfRangeException>("index", () => collection.Insert(index, viewEngine));
}
[InlineData]
public void ViewEngineDescriptors_AddsTypesAndInstances()
{
// Arrange
var viewEngine = Mock.Of<IViewEngine>();
var type = typeof(TestViewEngine);
var collection = new List<ViewEngineDescriptor>();
// Act
collection.Add(viewEngine);
collection.Insert(0, type);
// Assert
Assert.Equal(2, collection.Count);
Assert.IsType<TestViewEngine>(collection[0].ViewEngine);
Assert.Same(viewEngine, collection[0].ViewEngineType);
}
[Fact]
public void InputviewEngines_InstanceOf_ThrowsInvalidOperationExceptionIfMoreThanOnceInstance()
{
// Arrange
var viewEngines = new MvcViewOptions().ViewEngines;
viewEngines.Add(new TestViewEngine());
viewEngines.Add(Mock.Of<IViewEngine>());
viewEngines.Add(new TestViewEngine());
// Act & Assert
Assert.Throws<InvalidOperationException>(() => viewEngines.InstanceOf<TestViewEngine>());
}
[Fact]
public void InputviewEngines_InstanceOf_ThrowsInvalidOperationExceptionIfNoInstance()
{
// Arrange
var viewEngines = new MvcViewOptions().ViewEngines;
viewEngines.Add(Mock.Of<IViewEngine>());
viewEngines.Add(typeof(TestViewEngine));
// Act & Assert
Assert.Throws<InvalidOperationException>(() => viewEngines.InstanceOf<TestViewEngine>());
}
[Fact]
public void InputviewEngines_InstanceOf_ReturnsInstanceOfIInputFormatterIfOneExists()
{
// Arrange
var viewEngines = new MvcViewOptions().ViewEngines;
viewEngines.Add(Mock.Of<IViewEngine>());
var testEngine = new TestViewEngine();
viewEngines.Add(testEngine);
viewEngines.Add(typeof(TestViewEngine));
// Act
var formatter = viewEngines.InstanceOf<TestViewEngine>();
// Assert
Assert.NotNull(formatter);
Assert.IsType<TestViewEngine>(formatter);
Assert.Same(testEngine, formatter);
}
[Fact]
public void InputviewEngines_InstanceOfOrDefault_ThrowsInvalidOperationExceptionIfMoreThanOnceInstance()
{
// Arrange
var viewEngines = new MvcViewOptions().ViewEngines;
viewEngines.Add(new TestViewEngine());
viewEngines.Add(Mock.Of<IViewEngine>());
viewEngines.Add(new TestViewEngine());
// Act & Assert
Assert.Throws<InvalidOperationException>(() => viewEngines.InstanceOfOrDefault<TestViewEngine>());
}
[Fact]
public void InputviewEngines_InstanceOfOrDefault_ReturnsNullIfNoInstance()
{
// Arrange
var viewEngines = new MvcViewOptions().ViewEngines;
viewEngines.Add(Mock.Of<IViewEngine>());
viewEngines.Add(typeof(TestViewEngine));
// Act
var formatter = viewEngines.InstanceOfOrDefault<TestViewEngine>();
// Assert
Assert.Null(formatter);
}
[Fact]
public void InputviewEngines_InstanceOfOrDefault_ReturnsInstanceOfIInputFormatterIfOneExists()
{
// Arrange
var viewEngines = new MvcViewOptions().ViewEngines;
viewEngines.Add(Mock.Of<IViewEngine>());
viewEngines.Add(typeof(TestViewEngine));
var testEngine = new TestViewEngine();
viewEngines.Add(testEngine);
// Act
var formatter = viewEngines.InstanceOfOrDefault<TestViewEngine>();
// Assert
Assert.NotNull(formatter);
Assert.IsType<TestViewEngine>(formatter);
Assert.Same(testEngine, formatter);
}
[Fact]
public void InputviewEngines_InstancesOf_ReturnsEmptyCollectionIfNoneExist()
{
// Arrange
var viewEngines = new MvcViewOptions().ViewEngines;
viewEngines.Add(Mock.Of<IViewEngine>());
viewEngines.Add(typeof(TestViewEngine));
// Act
var result = viewEngines.InstancesOf<TestViewEngine>();
// Assert
Assert.Empty(result);
}
[Fact]
public void InputviewEngines_InstancesOf_ReturnsNonEmptyCollectionIfSomeExist()
{
// Arrange
var viewEngines = new MvcViewOptions().ViewEngines;
viewEngines.Add(typeof(TestViewEngine));
var viewEngine1 = new TestViewEngine();
var viewEngine2 = Mock.Of<IViewEngine>();
var viewEngine3 = new TestViewEngine();
var viewEngine4 = Mock.Of<IViewEngine>();
viewEngines.Add(viewEngine1);
viewEngines.Add(viewEngine2);
viewEngines.Add(viewEngine3);
viewEngines.Add(viewEngine4);
var expectedviewEngines = new List<TestViewEngine> { viewEngine1, viewEngine3 };
// Act
var result = viewEngines.InstancesOf<TestViewEngine>().ToList();
// Assert
Assert.NotEmpty(result);
Assert.Equal(result, expectedviewEngines);
}
private class TestViewEngine : IViewEngine
{
public ViewEngineResult FindPartialView(ActionContext context, string partialViewName)
{
throw new NotImplementedException();
}
public ViewEngineResult FindView(ActionContext context, string viewName)
{
throw new NotImplementedException();
}
}
}
}

View File

@ -1,67 +0,0 @@
// 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 Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Testing;
using Xunit;
namespace Microsoft.AspNet.Mvc.OptionDescriptors
{
public class ViewEngineDescriptorTest
{
[Fact]
public void ConstructorThrows_IfTypeIsNotViewEngine()
{
// Arrange
var viewEngineType = typeof(IViewEngine).FullName;
var type = typeof(string);
var expected = string.Format("The type '{0}' must derive from '{1}'.",
type.FullName, viewEngineType);
// Act & Assert
ExceptionAssert.ThrowsArgument(() => new ViewEngineDescriptor(type), "type", expected);
}
[Fact]
public void ConstructorSetsViewEngineType()
{
// Arrange
var type = typeof(TestViewEngine);
// Act
var descriptor = new ViewEngineDescriptor(type);
// Assert
Assert.Equal(type, descriptor.ViewEngineType);
Assert.Null(descriptor.ViewEngine);
}
[Fact]
public void ConstructorSetsViewEngineAndViewEngineType()
{
// Arrange
var viewEngine = new TestViewEngine();
// Act
var descriptor = new ViewEngineDescriptor(viewEngine);
// Assert
Assert.Same(viewEngine, descriptor.ViewEngine);
Assert.Equal(viewEngine.GetType(), descriptor.ViewEngineType);
}
private class TestViewEngine : IViewEngine
{
public ViewEngineResult FindPartialView(ActionContext context, string partialViewName)
{
throw new NotImplementedException();
}
public ViewEngineResult FindView(ActionContext context, string viewName)
{
throw new NotImplementedException();
}
}
}
}

View File

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Mvc;
using Microsoft.Framework.DependencyInjection;
namespace CompositeViewEngineWebSite
@ -16,7 +15,7 @@ namespace CompositeViewEngineWebSite
services.AddMvc()
.ConfigureMvcViews(options =>
{
options.ViewEngines.Insert(0, typeof(TestViewEngine));
options.ViewEngines.Insert(0, new TestViewEngine());
});
}