From 5194adfaf5575bee74108c8b731de8932629075d Mon Sep 17 00:00:00 2001 From: Pranav K Date: Mon, 30 Jun 2014 16:17:40 -0700 Subject: [PATCH] Moving IViewEngine to MvcOptions --- .../ActionResults/ViewResult.cs | 2 +- .../ViewEngineDescriptorExtensions.cs | 83 +++++++++++ .../Microsoft.AspNet.Mvc.Core.kproj | 6 + src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs | 8 ++ .../Properties/Resources.Designer.cs | 16 +++ .../Rendering/CompositeViewEngine.cs | 57 ++++++++ .../Rendering/DefaultViewEngineProvider.cs | 50 +++++++ .../Rendering/Html/DefaultDisplayTemplates.cs | 4 +- .../Rendering/Html/DefaultEditorTemplates.cs | 4 +- .../Rendering/Html/HtmlHelper.cs | 4 +- .../Rendering/Html/HtmlHelperOfT.cs | 2 +- .../Rendering/Html/TemplateBuilder.cs | 2 - .../Rendering/ICompositeViewEngine.cs | 12 ++ .../Rendering/IViewEngineProvider.cs | 18 +++ .../Rendering/ViewEngineDescriptor.cs | 58 ++++++++ src/Microsoft.AspNet.Mvc.Core/Resources.resx | 3 + .../ViewComponents/ViewComponent.cs | 4 +- .../Microsoft.AspNet.Mvc.kproj | 1 + src/Microsoft.AspNet.Mvc/MvcOptionsSetup.cs | 26 ++++ src/Microsoft.AspNet.Mvc/MvcServices.cs | 6 +- .../ViewEngineDscriptorExtensionsTest.cs | 79 +++++++++++ .../Microsoft.AspNet.Mvc.Core.Test.kproj | 4 + .../Rendering/CompositeViewEngineTest.cs | 131 ++++++++++++++++++ .../Rendering/DefaultDisplayTemplatesTests.cs | 10 +- .../Rendering/DefaultEditorTemplatesTests.cs | 10 +- .../Rendering/DefaultTemplatesUtilities.cs | 13 +- .../DefaultViewEngineProviderTest.cs | 70 ++++++++++ .../Rendering/ViewEngineDescriptorTest.cs | 67 +++++++++ .../ViewResultTest.cs | 15 +- 29 files changed, 730 insertions(+), 35 deletions(-) create mode 100644 src/Microsoft.AspNet.Mvc.Core/Extensions/ViewEngineDescriptorExtensions.cs create mode 100644 src/Microsoft.AspNet.Mvc.Core/Rendering/CompositeViewEngine.cs create mode 100644 src/Microsoft.AspNet.Mvc.Core/Rendering/DefaultViewEngineProvider.cs create mode 100644 src/Microsoft.AspNet.Mvc.Core/Rendering/ICompositeViewEngine.cs create mode 100644 src/Microsoft.AspNet.Mvc.Core/Rendering/IViewEngineProvider.cs create mode 100644 src/Microsoft.AspNet.Mvc.Core/Rendering/ViewEngineDescriptor.cs create mode 100644 src/Microsoft.AspNet.Mvc/MvcOptionsSetup.cs create mode 100644 test/Microsoft.AspNet.Mvc.Core.Test/Extensions/ViewEngineDscriptorExtensionsTest.cs create mode 100644 test/Microsoft.AspNet.Mvc.Core.Test/Rendering/CompositeViewEngineTest.cs create mode 100644 test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultViewEngineProviderTest.cs create mode 100644 test/Microsoft.AspNet.Mvc.Core.Test/Rendering/ViewEngineDescriptorTest.cs diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionResults/ViewResult.cs b/src/Microsoft.AspNet.Mvc.Core/ActionResults/ViewResult.cs index 5039eaa883..4513b39299 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionResults/ViewResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionResults/ViewResult.cs @@ -24,7 +24,7 @@ namespace Microsoft.AspNet.Mvc public override async Task ExecuteResultAsync([NotNull] ActionContext context) { - var viewEngine = ViewEngine ?? context.HttpContext.RequestServices.GetService(); + var viewEngine = ViewEngine ?? context.HttpContext.RequestServices.GetService(); var viewName = ViewName ?? context.ActionDescriptor.Name; var view = FindView(viewEngine, context.RouteData.Values, viewName); diff --git a/src/Microsoft.AspNet.Mvc.Core/Extensions/ViewEngineDescriptorExtensions.cs b/src/Microsoft.AspNet.Mvc.Core/Extensions/ViewEngineDescriptorExtensions.cs new file mode 100644 index 0000000000..a7ccf21e3b --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/Extensions/ViewEngineDescriptorExtensions.cs @@ -0,0 +1,83 @@ +// 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 Microsoft.AspNet.Mvc.Rendering; + +namespace Microsoft.AspNet.Mvc +{ + /// + /// Extension methods for adding model binders to a collection. + /// + public static class ViewEngineDescriptorExtensions + { + /// + /// Adds a type representing a to a descriptor collection. + /// + /// A list of ViewEngineDescriptors + /// Type representing an . + /// ViewEngineDescriptor representing the added instance. + public static ViewEngineDescriptor Add([NotNull] this IList descriptors, + [NotNull] Type viewEngineType) + { + var descriptor = new ViewEngineDescriptor(viewEngineType); + descriptors.Add(descriptor); + return descriptor; + } + + /// + /// Inserts a type representing a to a descriptor collection. + /// + /// A list of ViewEngineDescriptors + /// Type representing an . + /// ViewEngineDescriptor representing the inserted instance. + public static ViewEngineDescriptor Insert([NotNull] this IList descriptors, + int index, + [NotNull] Type viewEngineType) + { + if (index < 0 || index > descriptors.Count) + { + throw new ArgumentOutOfRangeException("index"); + } + + var descriptor = new ViewEngineDescriptor(viewEngineType); + descriptors.Insert(index, descriptor); + return descriptor; + } + + /// + /// Adds an to a descriptor collection. + /// + /// A list of ViewEngineDescriptors + /// An instance. + /// ViewEngineDescriptor representing the added instance. + public static ViewEngineDescriptor Add([NotNull] this IList descriptors, + [NotNull] IViewEngine viewEngine) + { + var descriptor = new ViewEngineDescriptor(viewEngine); + descriptors.Add(descriptor); + return descriptor; + } + + /// + /// Insert an to a descriptor collection. + /// + /// A list of ViewEngineDescriptors + /// An instance. + /// ViewEngineDescriptor representing the added instance. + public static ViewEngineDescriptor Insert([NotNull] this IList descriptors, + int index, + [NotNull] IViewEngine viewEngine) + { + if (index < 0 || index > descriptors.Count) + { + throw new ArgumentOutOfRangeException("index"); + } + + var descriptor = new ViewEngineDescriptor(viewEngine); + descriptors.Insert(index, descriptor); + return descriptor; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Core/Microsoft.AspNet.Mvc.Core.kproj b/src/Microsoft.AspNet.Mvc.Core/Microsoft.AspNet.Mvc.Core.kproj index b2a02ec1b1..2c2fa4185b 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Microsoft.AspNet.Mvc.Core.kproj +++ b/src/Microsoft.AspNet.Mvc.Core/Microsoft.AspNet.Mvc.Core.kproj @@ -27,6 +27,7 @@ + @@ -157,6 +158,8 @@ + + @@ -192,16 +195,19 @@ + + + diff --git a/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs b/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs index 0604ae95aa..1e0181e0a7 100644 --- a/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs +++ b/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using Microsoft.AspNet.Mvc.Core; using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ReflectedModelBuilder; +using Microsoft.AspNet.Mvc.Rendering; namespace Microsoft.AspNet.Mvc { @@ -24,6 +25,8 @@ namespace Microsoft.AspNet.Mvc new ModelBinderDescriptor(new MutableObjectModelBinder()), new ModelBinderDescriptor(new ComplexModelDtoModelBinder()), }; + + ViewEngines = new List(); } public AntiForgeryOptions AntiForgeryOptions @@ -48,6 +51,11 @@ namespace Microsoft.AspNet.Mvc public List ModelBinders { get; private set; } + /// + /// Gets a list of descriptors that represent used by this application. + /// + public List ViewEngines { get; private set; } + public List ApplicationModelConventions { get; private set; } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Core/Properties/Resources.Designer.cs b/src/Microsoft.AspNet.Mvc.Core/Properties/Resources.Designer.cs index bbaaabeafb..28e8b6f189 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Properties/Resources.Designer.cs @@ -1034,6 +1034,22 @@ namespace Microsoft.AspNet.Mvc.Core return string.Format(CultureInfo.CurrentCulture, GetString("ValueTypesCannotBeActivated"), p0); } + /// + /// The type '{0}' must derive from '{1}'. + /// + internal static string TypeMustDeriveFromType + { + get { return GetString("TypeMustDeriveFromType"); } + } + + /// + /// The type '{0}' must derive from '{1}'. + /// + internal static string FormatTypeMustDeriveFromType(object p0, object p1) + { + return string.Format(CultureInfo.CurrentCulture, GetString("TypeMustDeriveFromType"), p0, p1); + } + private static string GetString(string name, params string[] formatterNames) { var value = _resourceManager.GetString(name); diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/CompositeViewEngine.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/CompositeViewEngine.cs new file mode 100644 index 0000000000..79fe458eb4 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/CompositeViewEngine.cs @@ -0,0 +1,57 @@ +// 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.Linq; + +namespace Microsoft.AspNet.Mvc.Rendering +{ + /// + public class CompositeViewEngine : ICompositeViewEngine + { + public CompositeViewEngine(IViewEngineProvider viewEngineProvider) + { + ViewEngines = viewEngineProvider.ViewEngines; + } + + /// + /// Gets the list of ViewEngines the CompositeViewEngine delegates to. + /// + public IReadOnlyList ViewEngines { get; private set; } + + /// + public ViewEngineResult FindPartialView([NotNull] IDictionary context, + [NotNull] string partialViewName) + { + return FindView(context, partialViewName, partial: true); + } + + /// + public ViewEngineResult FindView([NotNull] IDictionary context, + [NotNull] string viewName) + { + return FindView(context, viewName, partial: false); + } + + private ViewEngineResult FindView(IDictionary context, + string viewName, + bool partial) + { + var searchedLocations = Enumerable.Empty(); + foreach (var engine in ViewEngines) + { + var result = partial ? engine.FindPartialView(context, viewName) : + engine.FindView(context, viewName); + + if (result.Success) + { + return result; + } + searchedLocations = searchedLocations.Concat(result.SearchedLocations); + } + + return ViewEngineResult.NotFound(viewName, searchedLocations); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/DefaultViewEngineProvider.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/DefaultViewEngineProvider.cs new file mode 100644 index 0000000000..fc5802c232 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/DefaultViewEngineProvider.cs @@ -0,0 +1,50 @@ +// 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 Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.OptionsModel; + +namespace Microsoft.AspNet.Mvc.Rendering +{ + /// + public class DefaultViewEngineProvider : IViewEngineProvider + { + private readonly IList _descriptors; + private readonly ITypeActivator _typeActivator; + private readonly IServiceProvider _serviceProvider; + + public DefaultViewEngineProvider( + ITypeActivator typeActivator, + IServiceProvider serviceProvider, + IOptionsAccessor options) + { + _typeActivator = typeActivator; + _serviceProvider = serviceProvider; + _descriptors = options.Options.ViewEngines; + } + + /// + public IReadOnlyList ViewEngines + { + get + { + var viewEngines = new List(_descriptors.Count); + foreach (var descriptor in _descriptors) + { + var viewEngine = descriptor.ViewEngine; + if (viewEngine == null) + { + viewEngine = (IViewEngine)_typeActivator.CreateInstance(_serviceProvider, + descriptor.ViewEngineType); + } + + viewEngines.Add(viewEngine); + } + + return viewEngines; + } + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/DefaultDisplayTemplates.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/DefaultDisplayTemplates.cs index 8ae11179d4..746d7456b2 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/DefaultDisplayTemplates.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/DefaultDisplayTemplates.cs @@ -125,7 +125,7 @@ namespace Microsoft.AspNet.Mvc.Rendering var serviceProvider = html.ViewContext.HttpContext.RequestServices; var metadataProvider = serviceProvider.GetService(); - var viewEngine = serviceProvider.GetService(); + var viewEngine = serviceProvider.GetService(); var index = 0; foreach (var item in collection) @@ -213,7 +213,7 @@ namespace Microsoft.AspNet.Mvc.Rendering } var serviceProvider = html.ViewContext.HttpContext.RequestServices; - var viewEngine = serviceProvider.GetService(); + var viewEngine = serviceProvider.GetService(); foreach (var propertyMetadata in modelMetadata.Properties.Where(pm => ShouldShow(pm, templateInfo))) { diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/DefaultEditorTemplates.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/DefaultEditorTemplates.cs index 52254e2b98..c0c58f9694 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/DefaultEditorTemplates.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/DefaultEditorTemplates.cs @@ -80,7 +80,7 @@ namespace Microsoft.AspNet.Mvc.Rendering var serviceProvider = html.ViewContext.HttpContext.RequestServices; var metadataProvider = serviceProvider.GetService(); - var viewEngine = serviceProvider.GetService(); + var viewEngine = serviceProvider.GetService(); var index = 0; foreach (var item in collection) @@ -214,7 +214,7 @@ namespace Microsoft.AspNet.Mvc.Rendering } var serviceProvider = html.ViewContext.HttpContext.RequestServices; - var viewEngine = serviceProvider.GetService(); + var viewEngine = serviceProvider.GetService(); foreach (var propertyMetadata in modelMetadata.Properties.Where(pm => ShouldShow(pm, templateInfo))) { diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs index 1694d55388..3c54f8431f 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs @@ -32,7 +32,7 @@ namespace Microsoft.AspNet.Mvc.Rendering private const string HiddenListItem = @"
  • "; private readonly IUrlHelper _urlHelper; - private readonly IViewEngine _viewEngine; + private readonly ICompositeViewEngine _viewEngine; private readonly AntiForgery _antiForgeryInstance; private readonly IActionBindingContextProvider _actionBindingContextProvider; @@ -42,7 +42,7 @@ namespace Microsoft.AspNet.Mvc.Rendering /// Initializes a new instance of the class. /// public HtmlHelper( - [NotNull] IViewEngine viewEngine, + [NotNull] ICompositeViewEngine viewEngine, [NotNull] IModelMetadataProvider metadataProvider, [NotNull] IUrlHelper urlHelper, [NotNull] AntiForgery antiForgeryInstance, diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelperOfT.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelperOfT.cs index da66a00054..f52d9932cf 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelperOfT.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelperOfT.cs @@ -16,7 +16,7 @@ namespace Microsoft.AspNet.Mvc.Rendering /// Initializes a new instance of the class. /// public HtmlHelper( - [NotNull] IViewEngine viewEngine, + [NotNull] ICompositeViewEngine viewEngine, [NotNull] IModelMetadataProvider metadataProvider, [NotNull] IUrlHelper urlHelper, [NotNull] AntiForgery antiForgeryInstance, diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/TemplateBuilder.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/TemplateBuilder.cs index d626f88e34..f354bf9127 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/TemplateBuilder.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/TemplateBuilder.cs @@ -1,8 +1,6 @@ // 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.Globalization; using Microsoft.AspNet.Mvc.ModelBinding; diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/ICompositeViewEngine.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/ICompositeViewEngine.cs new file mode 100644 index 0000000000..3a72faf479 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/ICompositeViewEngine.cs @@ -0,0 +1,12 @@ +// 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. + +namespace Microsoft.AspNet.Mvc.Rendering +{ + /// + /// Represents an that delegates to one of a collection of view engines. + /// + public interface ICompositeViewEngine : IViewEngine + { + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/IViewEngineProvider.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/IViewEngineProvider.cs new file mode 100644 index 0000000000..c6cef3e82d --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/IViewEngineProvider.cs @@ -0,0 +1,18 @@ +// 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.Collections.Generic; + +namespace Microsoft.AspNet.Mvc.Rendering +{ + /// + /// Provides an activated collection of instances. + /// + public interface IViewEngineProvider + { + /// + /// Gets a collection of activated IViewEngine instances. + /// + IReadOnlyList ViewEngines { get; } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/ViewEngineDescriptor.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/ViewEngineDescriptor.cs new file mode 100644 index 0000000000..b7b9973ba2 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/ViewEngineDescriptor.cs @@ -0,0 +1,58 @@ +// 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 Microsoft.AspNet.Mvc.Core; + +namespace Microsoft.AspNet.Mvc.Rendering +{ + /// + /// Encapsulates information that describes an . + /// + public class ViewEngineDescriptor + { + /// + /// Creates a new instance of . + /// + /// The + /// Creates a new instance of . + /// + /// An instance of that the descriptor represents. + public ViewEngineDescriptor([NotNull] IViewEngine viewEngine) + { + ViewEngine = viewEngine; + ViewEngineType = viewEngine.GetType(); + } + + /// + /// Gets the type of the . + /// + public Type ViewEngineType + { + get; + private set; + } + + /// + /// Gets the instance of the . + /// + public IViewEngine ViewEngine + { + get; + private set; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Core/Resources.resx b/src/Microsoft.AspNet.Mvc.Core/Resources.resx index 6b2eee5841..63b76fcaa7 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Resources.resx +++ b/src/Microsoft.AspNet.Mvc.Core/Resources.resx @@ -309,4 +309,7 @@ Value types cannot be activated by '{0}'. + + The type '{0}' must derive from '{1}'. + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/ViewComponent.cs b/src/Microsoft.AspNet.Mvc.Core/ViewComponents/ViewComponent.cs index e6de823b01..0b42aaf172 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/ViewComponent.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ViewComponents/ViewComponent.cs @@ -10,7 +10,7 @@ namespace Microsoft.AspNet.Mvc public abstract class ViewComponent { private dynamic _viewBag; - private IViewEngine _viewEngine; + private ICompositeViewEngine _viewEngine; public HttpContext Context { @@ -39,7 +39,7 @@ namespace Microsoft.AspNet.Mvc return new ContentViewComponentResult(content); } - public void Initialize(IViewEngine viewEngine) + public void Initialize(ICompositeViewEngine viewEngine) { _viewEngine = viewEngine; } diff --git a/src/Microsoft.AspNet.Mvc/Microsoft.AspNet.Mvc.kproj b/src/Microsoft.AspNet.Mvc/Microsoft.AspNet.Mvc.kproj index aed005034f..4ca3981866 100644 --- a/src/Microsoft.AspNet.Mvc/Microsoft.AspNet.Mvc.kproj +++ b/src/Microsoft.AspNet.Mvc/Microsoft.AspNet.Mvc.kproj @@ -21,6 +21,7 @@ + diff --git a/src/Microsoft.AspNet.Mvc/MvcOptionsSetup.cs b/src/Microsoft.AspNet.Mvc/MvcOptionsSetup.cs new file mode 100644 index 0000000000..607ec2c136 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc/MvcOptionsSetup.cs @@ -0,0 +1,26 @@ +// 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 Microsoft.AspNet.Mvc.Razor; +using Microsoft.Framework.OptionsModel; + +namespace Microsoft.AspNet.Mvc +{ + /// + /// Sets up default options for . + /// + public class MvcOptionsSetup : IOptionsSetup + { + /// + public int Order + { + get { return 1; } + } + + /// + public void Setup(MvcOptions options) + { + options.ViewEngines.Add(typeof(RazorViewEngine)); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc/MvcServices.cs b/src/Microsoft.AspNet.Mvc/MvcServices.cs index e7e937e9a7..a61f9c31b1 100644 --- a/src/Microsoft.AspNet.Mvc/MvcServices.cs +++ b/src/Microsoft.AspNet.Mvc/MvcServices.cs @@ -11,6 +11,7 @@ using Microsoft.AspNet.Security; using Microsoft.Framework.ConfigurationModel; using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.DependencyInjection.NestedProviders; +using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Mvc { @@ -25,6 +26,8 @@ namespace Microsoft.AspNet.Mvc { var describe = new ServiceDescriber(configuration); + yield return describe.Transient, MvcOptionsSetup>(); + yield return describe.Transient(); yield return describe.Singleton(); yield return describe.Scoped(); @@ -36,9 +39,10 @@ namespace Microsoft.AspNet.Mvc yield return describe.Transient(); + yield return describe.Singleton(); + yield return describe.Scoped(); yield return describe.Transient(); yield return describe.Transient(); - yield return describe.Scoped(); yield return describe.Transient, ReflectedActionDescriptorProvider>(); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Extensions/ViewEngineDscriptorExtensionsTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Extensions/ViewEngineDscriptorExtensionsTest.cs new file mode 100644 index 0000000000..37f2940498 --- /dev/null +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Extensions/ViewEngineDscriptorExtensionsTest.cs @@ -0,0 +1,79 @@ +// 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. + +#if NET45 +using System; +using System.Collections.Generic; +using Moq; +using Xunit; + +namespace Microsoft.AspNet.Mvc.Rendering +{ + public class ViewEngineDescriptorExtensionTest + { + [Theory] + [InlineData(-1)] + [InlineData(5)] + public void Insert_WithType_ThrowsIfIndexIsOutOfBounds(int index) + { + // Arrange + var collection = new List + { + new ViewEngineDescriptor(Mock.Of()), + new ViewEngineDescriptor(Mock.Of()) + }; + + // Act & Assert + Assert.Throws("index", () => collection.Insert(index, typeof(IViewEngine))); + } + + [Theory] + [InlineData(-2)] + [InlineData(3)] + public void Insert_WithInstance_ThrowsIfIndexIsOutOfBounds(int index) + { + // Arrange + var collection = new List + { + new ViewEngineDescriptor(Mock.Of()), + new ViewEngineDescriptor(Mock.Of()) + }; + var viewEngine = Mock.Of(); + + // Act & Assert + Assert.Throws("index", () => collection.Insert(index, viewEngine)); + } + + [InlineData] + public void ViewEngineDescriptors_AddsTypesAndInstances() + { + // Arrange + var viewEngine = Mock.Of(); + var type = typeof(TestViewEngine); + var collection = new List(); + + // Act + collection.Add(viewEngine); + collection.Insert(0, type); + + // Assert + Assert.Equal(2, collection.Count); + Assert.IsType(collection[0].ViewEngine); + Assert.Same(viewEngine, collection[0].ViewEngine); + } + + private class TestViewEngine : IViewEngine + { + public ViewEngineResult FindPartialView([NotNull]IDictionary context, [NotNull]string partialViewName) + { + throw new NotImplementedException(); + } + + public ViewEngineResult FindView([NotNull]IDictionary context, [NotNull]string viewName) + { + throw new NotImplementedException(); + } + } + } +} +#endif \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Microsoft.AspNet.Mvc.Core.Test.kproj b/test/Microsoft.AspNet.Mvc.Core.Test/Microsoft.AspNet.Mvc.Core.Test.kproj index 1c9c7e260a..7d33a4dabf 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Microsoft.AspNet.Mvc.Core.Test.kproj +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Microsoft.AspNet.Mvc.Core.Test.kproj @@ -30,6 +30,7 @@ + @@ -60,6 +61,7 @@ + @@ -67,6 +69,8 @@ + + diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/CompositeViewEngineTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/CompositeViewEngineTest.cs new file mode 100644 index 0000000000..868912a513 --- /dev/null +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/CompositeViewEngineTest.cs @@ -0,0 +1,131 @@ +// 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.Collections.Generic; +using System.Linq; +using Moq; +using Xunit; + +namespace Microsoft.AspNet.Mvc.Rendering +{ + public class CompositeViewEngineTest + { + [Fact] + public void FindView_ReturnsViewFromFirstViewEngineWithFoundResult() + { + // Arrange + var viewName = "foo"; + var engine1 = new Mock(); + var engine2 = new Mock(); + var engine3 = new Mock(); + var view2 = Mock.Of(); + var view3 = Mock.Of(); + engine1.Setup(e => e.FindView(It.IsAny>(), It.IsAny())) + .Returns(ViewEngineResult.NotFound(viewName, Enumerable.Empty())); + engine2.Setup(e => e.FindView(It.IsAny>(), It.IsAny())) + .Returns(ViewEngineResult.Found(viewName, view2)); + engine3.Setup(e => e.FindView(It.IsAny>(), It.IsAny())) + .Returns(ViewEngineResult.Found(viewName, view3)); + + var provider = new Mock(); + provider.SetupGet(p => p.ViewEngines) + .Returns(new[] { engine1.Object, engine2.Object, engine3.Object }); + var compositeViewEngine = new CompositeViewEngine(provider.Object); + + // Act + var result = compositeViewEngine.FindView(new Dictionary(), viewName); + + // Assert + Assert.True(result.Success); + Assert.Same(view2, result.View); + Assert.Equal(viewName, result.ViewName); + } + + [Fact] + public void FindView_ReturnsNotFound_IfAllViewEnginesReturnNotFound() + { + // Arrange + var viewName = "foo"; + var engine1 = new Mock(); + var engine2 = new Mock(); + var engine3 = new Mock(); + engine1.Setup(e => e.FindView(It.IsAny>(), It.IsAny())) + .Returns(ViewEngineResult.NotFound(viewName, new[] { "1", "2" })); + engine2.Setup(e => e.FindView(It.IsAny>(), It.IsAny())) + .Returns(ViewEngineResult.NotFound(viewName, new[] { "3" })); + engine3.Setup(e => e.FindView(It.IsAny>(), It.IsAny())) + .Returns(ViewEngineResult.NotFound(viewName, new[] { "4", "5" })); + + var provider = new Mock(); + provider.SetupGet(p => p.ViewEngines) + .Returns(new[] { engine1.Object, engine2.Object, engine3.Object }); + var compositeViewEngine = new CompositeViewEngine(provider.Object); + + // Act + var result = compositeViewEngine.FindView(new Dictionary(), viewName); + + // Assert + Assert.False(result.Success); + Assert.Equal(new[] { "1", "2", "3", "4", "5" }, result.SearchedLocations); + } + + [Fact] + public void FindPartialView_ReturnsViewFromFirstViewEngineWithFoundResult() + { + // Arrange + var viewName = "bar"; + var engine1 = new Mock(); + var engine2 = new Mock(); + var engine3 = new Mock(); + var view2 = Mock.Of(); + var view3 = Mock.Of(); + engine1.Setup(e => e.FindPartialView(It.IsAny>(), It.IsAny())) + .Returns(ViewEngineResult.NotFound(viewName, Enumerable.Empty())); + engine2.Setup(e => e.FindPartialView(It.IsAny>(), It.IsAny())) + .Returns(ViewEngineResult.Found(viewName, view2)); + engine3.Setup(e => e.FindPartialView(It.IsAny>(), It.IsAny())) + .Returns(ViewEngineResult.Found(viewName, view3)); + + var provider = new Mock(); + provider.SetupGet(p => p.ViewEngines) + .Returns(new[] { engine1.Object, engine2.Object, engine3.Object }); + var compositeViewEngine = new CompositeViewEngine(provider.Object); + + // Act + var result = compositeViewEngine.FindPartialView(new Dictionary(), viewName); + + // Assert + Assert.True(result.Success); + Assert.Same(view2, result.View); + Assert.Equal(viewName, result.ViewName); + } + + [Fact] + public void FindPartialView_ReturnsNotFound_IfAllViewEnginesReturnNotFound() + { + // Arrange + var viewName = "foo"; + var engine1 = new Mock(); + var engine2 = new Mock(); + var engine3 = new Mock(); + engine1.Setup(e => e.FindPartialView(It.IsAny>(), It.IsAny())) + .Returns(ViewEngineResult.NotFound(viewName, new[] { "1", "2" })); + engine2.Setup(e => e.FindPartialView(It.IsAny>(), It.IsAny())) + .Returns(ViewEngineResult.NotFound(viewName, new[] { "3" })); + engine3.Setup(e => e.FindPartialView(It.IsAny>(), It.IsAny())) + .Returns(ViewEngineResult.NotFound(viewName, new[] { "4", "5" })); + + var provider = new Mock(); + provider.SetupGet(p => p.ViewEngines) + .Returns(new[] { engine1.Object, engine2.Object, engine3.Object }); + var compositeViewEngine = new CompositeViewEngine(provider.Object); + + // Act + var result = compositeViewEngine.FindPartialView(new Dictionary(), viewName); + + // Assert + Assert.False(result.Success); + Assert.Equal(new[] { "1", "2", "3", "4", "5" }, result.SearchedLocations); + } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultDisplayTemplatesTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultDisplayTemplatesTests.cs index f4dc5ceb47..acbfdbad0d 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultDisplayTemplatesTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultDisplayTemplatesTests.cs @@ -85,7 +85,7 @@ namespace Microsoft.AspNet.Mvc.Core
    "; var model = new DefaultTemplatesUtilities.ObjectWithScaffoldColumn(); - var viewEngine = new Mock(); + var viewEngine = new Mock(); viewEngine.Setup(v => v.FindPartialView(It.IsAny>(), It.IsAny())) .Returns(ViewEngineResult.NotFound("", Enumerable.Empty())); var htmlHelper = DefaultTemplatesUtilities.GetHtmlHelper(model, viewEngine.Object); @@ -102,7 +102,7 @@ namespace Microsoft.AspNet.Mvc.Core { // Arrange var model = new DefaultTemplatesUtilities.ObjectTemplateModel { Property1 = "Model string" }; - var viewEngine = new Mock(); + var viewEngine = new Mock(); viewEngine .Setup(v => v.FindPartialView(It.IsAny>(), It.IsAny())) .Returns(ViewEngineResult.NotFound("", Enumerable.Empty())); @@ -121,7 +121,7 @@ namespace Microsoft.AspNet.Mvc.Core { // Arrange var model = new DefaultTemplatesUtilities.ObjectTemplateModel { Property1 = "Model string" }; - var viewEngine = new Mock(); + var viewEngine = new Mock(); viewEngine .Setup(v => v.FindPartialView(It.IsAny>(), It.IsAny())) .Returns(ViewEngineResult.NotFound("", Enumerable.Empty())); @@ -140,7 +140,7 @@ namespace Microsoft.AspNet.Mvc.Core { // Arrange var model = new DefaultTemplatesUtilities.ObjectTemplateModel { Property1 = "Model string" }; - var viewEngine = new Mock(); + var viewEngine = new Mock(); viewEngine .Setup(v => v.FindPartialView(It.IsAny>(), It.IsAny())) .Returns(ViewEngineResult.NotFound("", Enumerable.Empty())); @@ -160,7 +160,7 @@ namespace Microsoft.AspNet.Mvc.Core { // Arrange var model = new DefaultTemplatesUtilities.ObjectTemplateModel { Property1 = propertyValue, }; - var viewEngine = new Mock(); + var viewEngine = new Mock(); viewEngine .Setup(v => v.FindPartialView(It.IsAny>(), It.IsAny())) .Returns(ViewEngineResult.NotFound("", Enumerable.Empty())); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultEditorTemplatesTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultEditorTemplatesTests.cs index 52b5cb6cc7..e97a9abf47 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultEditorTemplatesTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultEditorTemplatesTests.cs @@ -93,7 +93,7 @@ Environment.NewLine + Environment.NewLine; var model = new DefaultTemplatesUtilities.ObjectWithScaffoldColumn(); - var viewEngine = new Mock(); + var viewEngine = new Mock(); viewEngine.Setup(v => v.FindPartialView(It.IsAny>(), It.IsAny())) .Returns(ViewEngineResult.NotFound("", Enumerable.Empty())); var htmlHelper = DefaultTemplatesUtilities.GetHtmlHelper(model, viewEngine.Object); @@ -110,7 +110,7 @@ Environment.NewLine; { // Arrange var model = new DefaultTemplatesUtilities.ObjectTemplateModel { Property1 = "Model string" }; - var viewEngine = new Mock(); + var viewEngine = new Mock(); viewEngine .Setup(v => v.FindPartialView(It.IsAny>(), It.IsAny())) .Returns(ViewEngineResult.NotFound("", Enumerable.Empty())); @@ -131,7 +131,7 @@ Environment.NewLine; { // Arrange var model = new DefaultTemplatesUtilities.ObjectTemplateModel { Property1 = "Model string" }; - var viewEngine = new Mock(); + var viewEngine = new Mock(); viewEngine .Setup(v => v.FindPartialView(It.IsAny>(), It.IsAny())) .Returns(ViewEngineResult.NotFound("", Enumerable.Empty())); @@ -152,7 +152,7 @@ Environment.NewLine; { // Arrange var model = new DefaultTemplatesUtilities.ObjectTemplateModel { Property1 = "Model string" }; - var viewEngine = new Mock(); + var viewEngine = new Mock(); viewEngine .Setup(v => v.FindPartialView(It.IsAny>(), It.IsAny())) .Returns(ViewEngineResult.NotFound("", Enumerable.Empty())); @@ -174,7 +174,7 @@ Environment.NewLine; { // Arrange var model = new DefaultTemplatesUtilities.ObjectTemplateModel { Property1 = propertyValue, }; - var viewEngine = new Mock(); + var viewEngine = new Mock(); viewEngine .Setup(v => v.FindPartialView(It.IsAny>(), It.IsAny())) .Returns(ViewEngineResult.NotFound("", Enumerable.Empty())); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultTemplatesUtilities.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultTemplatesUtilities.cs index 524b75de3a..a7cc20a903 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultTemplatesUtilities.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultTemplatesUtilities.cs @@ -63,14 +63,14 @@ namespace Microsoft.AspNet.Mvc.Core return GetHtmlHelper(model, CreateViewEngine(), provider); } - public static HtmlHelper GetHtmlHelper(TModel model, IViewEngine viewEngine) + public static HtmlHelper GetHtmlHelper(TModel model, ICompositeViewEngine viewEngine) { return GetHtmlHelper(model, viewEngine, new DataAnnotationsModelMetadataProvider()); } public static HtmlHelper GetHtmlHelper( TModel model, - IViewEngine viewEngine, + ICompositeViewEngine viewEngine, IModelMetadataProvider provider) { var viewData = new ViewDataDictionary(provider); @@ -102,7 +102,7 @@ namespace Microsoft.AspNet.Mvc.Core var serviceProvider = new Mock(); serviceProvider - .Setup(s => s.GetService(typeof(IViewEngine))) + .Setup(s => s.GetService(typeof(ICompositeViewEngine))) .Returns(viewEngine); serviceProvider .Setup(s => s.GetService(typeof(IUrlHelper))) @@ -110,7 +110,7 @@ namespace Microsoft.AspNet.Mvc.Core serviceProvider .Setup(s => s.GetService(typeof(IViewComponentHelper))) .Returns(new Mock().Object); - + httpContext .Setup(o => o.RequestServices) .Returns(serviceProvider.Object); @@ -138,7 +138,7 @@ namespace Microsoft.AspNet.Mvc.Core return htmlHelper; } - private static IViewEngine CreateViewEngine() + private static ICompositeViewEngine CreateViewEngine() { var view = new Mock(); view @@ -149,10 +149,11 @@ namespace Microsoft.AspNet.Mvc.Core }) .Returns(Task.FromResult(0)); - var viewEngine = new Mock(); + var viewEngine = new Mock(); viewEngine .Setup(v => v.FindPartialView(It.IsAny>(), It.IsAny())) .Returns(ViewEngineResult.Found("MyView", view.Object)); + return viewEngine.Object; } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultViewEngineProviderTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultViewEngineProviderTest.cs new file mode 100644 index 0000000000..7b1970c4d7 --- /dev/null +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultViewEngineProviderTest.cs @@ -0,0 +1,70 @@ +// 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. + +#if NET45 +using System; +using System.Collections.Generic; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.OptionsModel; +using Moq; +using Xunit; + +namespace Microsoft.AspNet.Mvc.Rendering +{ + public class DefaultViewEngineProviderTest + { + [Fact] + public void ViewEngine_ReturnsInstantiatedListOfViewEngines() + { + // Arrange + var service = Mock.Of(); + var viewEngine = Mock.Of(); + var type = typeof(TestViewEngine); + var typeActivator = new TypeActivator(); + var serviceProvider = new Mock(); + serviceProvider.Setup(p => p.GetService(typeof(ITestService))) + .Returns(service); + var options = new MvcOptions(); + options.ViewEngines.Add(viewEngine); + options.ViewEngines.Add(type); + var accessor = new Mock>(); + accessor.SetupGet(a => a.Options) + .Returns(options); + var provider = new DefaultViewEngineProvider(typeActivator, serviceProvider.Object, accessor.Object); + + // Act + var result = provider.ViewEngines; + + // Assert + Assert.Equal(2, result.Count); + Assert.Same(viewEngine, result[0]); + var testViewEngine = Assert.IsType(result[1]); + Assert.Same(service, testViewEngine.Service); + } + + private class TestViewEngine : IViewEngine + { + public TestViewEngine(ITestService service) + { + Service = service; + } + + public ITestService Service { get; private set; } + + public ViewEngineResult FindPartialView([NotNull]IDictionary context, [NotNull]string partialViewName) + { + throw new NotImplementedException(); + } + + public ViewEngineResult FindView([NotNull]IDictionary context, [NotNull]string viewName) + { + throw new NotImplementedException(); + } + } + + public interface ITestService + { + } + } +} +#endif \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/ViewEngineDescriptorTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/ViewEngineDescriptorTest.cs new file mode 100644 index 0000000000..2b6a0e48dc --- /dev/null +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/ViewEngineDescriptorTest.cs @@ -0,0 +1,67 @@ +// 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 Microsoft.AspNet.Testing; +using Xunit; + +namespace Microsoft.AspNet.Mvc.Rendering +{ + 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(IDictionary context, string partialViewName) + { + throw new NotImplementedException(); + } + + public ViewEngineResult FindView(IDictionary context, string viewName) + { + throw new NotImplementedException(); + } + } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ViewResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ViewResultTest.cs index 2ea8491b8c..4032b498b3 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ViewResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ViewResultTest.cs @@ -34,12 +34,13 @@ namespace Microsoft.AspNet.Mvc.Core.Test var routeDictionary = new Dictionary(); - var viewEngine = new Mock(); + var viewEngine = new Mock(); viewEngine.Setup(v => v.FindView(routeDictionary, It.IsAny())) .Returns(ViewEngineResult.Found("MyView", view.Object)); var serviceProvider = new Mock(); - serviceProvider.Setup(sp => sp.GetService(typeof(IViewEngine))).Returns(viewEngine.Object); + serviceProvider.Setup(sp => sp.GetService(typeof(ICompositeViewEngine))) + .Returns(viewEngine.Object); var memoryStream = new MemoryStream(); var response = new Mock(); @@ -86,10 +87,11 @@ namespace Microsoft.AspNet.Mvc.Core.Test goodViewEngine.Setup(v => v.FindView(routeDictionary, It.IsAny())) .Returns(ViewEngineResult.Found("MyView", view.Object)); - var badViewEngine = new Mock(MockBehavior.Strict); + var badViewEngine = new Mock(MockBehavior.Strict); var serviceProvider = new Mock(); - serviceProvider.Setup(sp => sp.GetService(typeof(IViewEngine))).Returns(badViewEngine.Object); + serviceProvider.Setup(sp => sp.GetService(typeof(ICompositeViewEngine))) + .Returns(badViewEngine.Object); var memoryStream = new MemoryStream(); var response = new Mock(); @@ -138,12 +140,13 @@ namespace Microsoft.AspNet.Mvc.Core.Test throw new Exception(); }); - var viewEngine = new Mock(); + var viewEngine = new Mock(); viewEngine.Setup(v => v.FindView(routeDictionary, It.IsAny())) .Returns(ViewEngineResult.Found("MyView", view.Object)); var serviceProvider = new Mock(); - serviceProvider.Setup(sp => sp.GetService(typeof(IViewEngine))).Returns(viewEngine.Object); + serviceProvider.Setup(sp => sp.GetService(typeof(ICompositeViewEngine))) + .Returns(viewEngine.Object); var memoryStream = new MemoryStream(); var response = new Mock();