From 07201772439684587054770f89e50db06440eaf0 Mon Sep 17 00:00:00 2001 From: ianhong Date: Wed, 12 Nov 2014 15:46:38 -0800 Subject: [PATCH] Updating per comments --- src/Microsoft.AspNet.Mvc.Razor/RazorView.cs | 60 ++++---- .../RazorViewEngine.cs | 8 +- .../RazorViewFactory.cs | 13 +- .../RazorViewEngineTest.cs | 42 ++++-- .../RazorViewFactoryTest.cs | 102 ++++++------- .../RazorViewTest.cs | 135 +++++++++--------- 6 files changed, 184 insertions(+), 176 deletions(-) diff --git a/src/Microsoft.AspNet.Mvc.Razor/RazorView.cs b/src/Microsoft.AspNet.Mvc.Razor/RazorView.cs index 468b76e93d..c1f2f0b214 100644 --- a/src/Microsoft.AspNet.Mvc.Razor/RazorView.cs +++ b/src/Microsoft.AspNet.Mvc.Razor/RazorView.cs @@ -11,7 +11,7 @@ namespace Microsoft.AspNet.Mvc.Razor { /// /// Default implementation for that executes one or more - /// instances as part of view rendering. + /// as parts of its exeuction. /// public class RazorView : IView { @@ -19,8 +19,6 @@ namespace Microsoft.AspNet.Mvc.Razor private readonly IRazorPageActivator _pageActivator; private readonly IViewStartProvider _viewStartProvider; private IPageExecutionListenerFeature _pageExecutionFeature; - private IRazorPage _razorPage; - private bool _isPartial; /// /// Initializes a new instance of RazorView @@ -28,52 +26,52 @@ namespace Microsoft.AspNet.Mvc.Razor /// The page factory used to instantiate layout and _ViewStart pages. /// The used to activate pages. /// The used for discovery of _ViewStart + /// The instance to execute. + /// Determines if the view is to be executed as a partial. /// pages public RazorView(IRazorPageFactory pageFactory, IRazorPageActivator pageActivator, - IViewStartProvider viewStartProvider) + IViewStartProvider viewStartProvider, + IRazorPage razorPage, + bool isPartial + ) { _pageFactory = pageFactory; _pageActivator = pageActivator; _viewStartProvider = viewStartProvider; + RazorPage = razorPage; + IsPartial = isPartial; } + /// + /// Gets instance that the views executes on. + /// + public IRazorPage RazorPage { get; } + + /// + /// Gets a value that determines if the view is executed as a partial. + /// + /// + public bool IsPartial { get; } + + private bool EnableInstrumentation { get { return _pageExecutionFeature != null; } } - /// - /// Contextualizes the current instance of the providing it with the - /// to execute. - /// - /// The instance to execute. - /// Determines if the view is to be executed as a partial. - public virtual void Contextualize([NotNull] IRazorPage razorPage, - bool isPartial) - { - _razorPage = razorPage; - _isPartial = isPartial; - } - /// public virtual async Task RenderAsync([NotNull] ViewContext context) { - if (_razorPage == null) - { - var message = Resources.FormatViewMustBeContextualized(nameof(Contextualize), nameof(RenderAsync)); - throw new InvalidOperationException(message); - } - _pageExecutionFeature = context.HttpContext.GetFeature(); - if (_isPartial) + if (IsPartial) { await RenderPartialAsync(context); } else { - var bodyWriter = await RenderPageAsync(_razorPage, context, executeViewStart: true); + var bodyWriter = await RenderPageAsync(RazorPage, context, executeViewStart: true); await RenderLayoutAsync(context, bodyWriter); } } @@ -84,14 +82,14 @@ namespace Microsoft.AspNet.Mvc.Razor { // When instrmenting, we need to Decorate the output in an instrumented writer which // RenderPageAsync does. - var bodyWriter = await RenderPageAsync(_razorPage, context, executeViewStart: false); + var bodyWriter = await RenderPageAsync(RazorPage, context, executeViewStart: false); await bodyWriter.CopyToAsync(context.Writer); } else { // For the non-instrumented case, we don't need to buffer contents. For Html.Partial, the writer is // an in memory writer and for Partial views, we directly write to the Response. - await RenderPageCoreAsync(_razorPage, context); + await RenderPageCoreAsync(RazorPage, context); } } @@ -142,7 +140,7 @@ namespace Microsoft.AspNet.Mvc.Razor private async Task RenderPageCoreAsync(IRazorPage page, ViewContext context) { - page.IsPartial = _isPartial; + page.IsPartial = IsPartial; page.ViewContext = context; if (EnableInstrumentation) { @@ -155,7 +153,7 @@ namespace Microsoft.AspNet.Mvc.Razor private async Task RenderViewStartAsync(ViewContext context) { - var viewStarts = _viewStartProvider.GetViewStartPages(_razorPage.Path); + var viewStarts = _viewStartProvider.GetViewStartPages(RazorPage.Path); string layout = null; foreach (var viewStart in viewStarts) @@ -167,7 +165,7 @@ namespace Microsoft.AspNet.Mvc.Razor } // Copy over interesting properties from the ViewStart page to the entry page. - _razorPage.Layout = layout; + RazorPage.Layout = layout; } private async Task RenderLayoutAsync(ViewContext context, @@ -175,7 +173,7 @@ namespace Microsoft.AspNet.Mvc.Razor { // A layout page can specify another layout page. We'll need to continue // looking for layout pages until they're no longer specified. - var previousPage = _razorPage; + var previousPage = RazorPage; while (!string.IsNullOrEmpty(previousPage.Layout)) { if (!bodyWriter.IsBuffering) diff --git a/src/Microsoft.AspNet.Mvc.Razor/RazorViewEngine.cs b/src/Microsoft.AspNet.Mvc.Razor/RazorViewEngine.cs index 74b6b3ccd1..9b84c22f56 100644 --- a/src/Microsoft.AspNet.Mvc.Razor/RazorViewEngine.cs +++ b/src/Microsoft.AspNet.Mvc.Razor/RazorViewEngine.cs @@ -34,7 +34,7 @@ namespace Microsoft.AspNet.Mvc.Razor }; private readonly IRazorPageFactory _pageFactory; - private readonly IRazorViewFactory _pageViewFactory; + private readonly IRazorViewFactory _viewFactory; private readonly IReadOnlyList _viewLocationExpanders; private readonly IViewLocationCache _viewLocationCache; @@ -43,12 +43,12 @@ namespace Microsoft.AspNet.Mvc.Razor /// /// The page factory used for creating instances. public RazorViewEngine(IRazorPageFactory pageFactory, - IRazorViewFactory pageViewFactory, + IRazorViewFactory viewFactory, IViewLocationExpanderProvider viewLocationExpanderProvider, IViewLocationCache viewLocationCache) { _pageFactory = pageFactory; - _pageViewFactory = pageViewFactory; + _viewFactory = viewFactory; _viewLocationExpanders = viewLocationExpanderProvider.ViewLocationExpanders; _viewLocationCache = viewLocationCache; } @@ -197,7 +197,7 @@ namespace Microsoft.AspNet.Mvc.Razor var services = actionContext.HttpContext.RequestServices; - var view = _pageViewFactory.GetView(page, partial); + var view = _viewFactory.GetView(page, partial); return ViewEngineResult.Found(viewName, view); } diff --git a/src/Microsoft.AspNet.Mvc.Razor/RazorViewFactory.cs b/src/Microsoft.AspNet.Mvc.Razor/RazorViewFactory.cs index 6b7044d71c..78c313eed1 100644 --- a/src/Microsoft.AspNet.Mvc.Razor/RazorViewFactory.cs +++ b/src/Microsoft.AspNet.Mvc.Razor/RazorViewFactory.cs @@ -5,6 +5,10 @@ using Microsoft.AspNet.Mvc.Rendering; namespace Microsoft.AspNet.Mvc.Razor { + /// + /// Represents the default implementation that creates + /// instances with a given . + /// public class RazorViewFactory : IRazorViewFactory { private readonly IRazorPageActivator _pageActivator; @@ -19,8 +23,8 @@ namespace Microsoft.AspNet.Mvc.Razor /// The used for discovery of _ViewStart /// pages public RazorViewFactory(IRazorPageFactory pageFactory, - IRazorPageActivator pageActivator, - IViewStartProvider viewStartProvider) + IRazorPageActivator pageActivator, + IViewStartProvider viewStartProvider) { _pageFactory = pageFactory; _pageActivator = pageActivator; @@ -30,10 +34,7 @@ namespace Microsoft.AspNet.Mvc.Razor /// public IView GetView([NotNull] IRazorPage page, bool isPartial) { - var razorView = new RazorView(_pageFactory, _pageActivator, _viewStartProvider); - - razorView.Contextualize(page, isPartial); - + var razorView = new RazorView(_pageFactory, _pageActivator, _viewStartProvider, page, isPartial); return razorView; } } diff --git a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewEngineTest.cs b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewEngineTest.cs index 46a9c474a1..6bbf13a9bc 100644 --- a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewEngineTest.cs +++ b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewEngineTest.cs @@ -83,6 +83,32 @@ namespace Microsoft.AspNet.Mvc.Razor.Test Assert.False(result.Success); } + [Fact] + public void FindPartialView_ReturnsRazorView_IfLookupWasSuccessful() + { + // Arrange + var pageFactory = new Mock(); + var viewFactory = new Mock(); + var page = Mock.Of(); + + pageFactory.Setup(p => p.CreateInstance(It.IsAny())) + .Returns(Mock.Of()); + viewFactory.Setup(p => p.GetView(It.IsAny(), It.IsAny())) + .Returns(Mock.Of()).Verifiable(); + + var viewEngine = CreateViewEngine(pageFactory.Object, viewFactory.Object); + var context = GetActionContext(_controllerTestContext); + + // Act + var result = viewEngine.FindPartialView(context, "test-view"); + + // Assert + Assert.True(result.Success); + Assert.IsAssignableFrom(result.View); + Assert.Equal("/Views/bar/test-view.cshtml", result.ViewName); + viewFactory.Verify(); + } + [Theory] [InlineData(null)] [InlineData("")] @@ -216,7 +242,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Test pageFactory.Setup(p => p.CreateInstance(It.IsAny())) .Returns(Mock.Of()); viewFactory.Setup(p => p.GetView(It.IsAny(), It.IsAny())) - .Returns(Mock.Of()); + .Returns(Mock.Of()).Verifiable(); var viewEngine = CreateViewEngine(pageFactory.Object, viewFactory.Object); var context = GetActionContext(_controllerTestContext); @@ -228,6 +254,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Test Assert.True(result.Success); Assert.IsAssignableFrom(result.View); Assert.Equal("/Views/bar/test-view.cshtml", result.ViewName); + viewFactory.Verify(); } [Fact] @@ -356,7 +383,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Test // Assert Assert.True(result.Success); - Assert.IsAssignableFrom(result.View); + Assert.IsAssignableFrom(result.View); pageFactory.Verify(); expander1.Verify(); expander2.Verify(); @@ -445,8 +472,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Test .Verifiable(); var viewFactory = new Mock(); - viewFactory.Setup(p => p.GetView(It.IsAny(), It.IsAny())) - .Returns(Mock.Of()); + viewFactory.Setup(p => p.GetView(It.IsAny(), It.IsAny())).Returns(Mock.Of()); var cacheMock = new Mock(); cacheMock.Setup(c => c.Get(It.IsAny())) @@ -463,9 +489,9 @@ namespace Microsoft.AspNet.Mvc.Razor.Test var viewEngine = CreateViewEngine(pageFactory.Object, viewFactory.Object, - new[] { expander.Object }, - cacheMock.Object); - var context = GetActionContext(_controllerTestContext); + expanders: new[] { expander.Object }, + cache: cacheMock.Object); + var context = GetActionContext(_controllerTestContext, viewFactory.Object); // Act var result = viewEngine.FindView(context, "baz"); @@ -520,8 +546,6 @@ namespace Microsoft.AspNet.Mvc.Razor.Test { var httpContext = new DefaultHttpContext(); var serviceProvider = new Mock(); - serviceProvider.Setup(p => p.GetService(typeof(IRazorViewFactory))) - .Returns(razorViewFactory ?? Mock.Of()); httpContext.RequestServices = serviceProvider.Object; diff --git a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewFactoryTest.cs b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewFactoryTest.cs index e350311c3d..bbc232285e 100644 --- a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewFactoryTest.cs +++ b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewFactoryTest.cs @@ -14,6 +14,46 @@ namespace Microsoft.AspNet.Mvc.Razor.Test { public class RazorViewFactoryTest { + + [Fact] + public void GetView_SetsIsPartial() + { + // Arrange + var factory = new RazorViewFactory( + Mock.Of(), + Mock.Of(), + Mock.Of()); + + // Act + var viewPartial = factory.GetView(Mock.Of(), isPartial: true) as RazorView; + var view = factory.GetView(Mock.Of(), isPartial: false) as RazorView; + + // Assert + Assert.NotNull(viewPartial); + Assert.True(viewPartial.IsPartial); + Assert.NotNull(view); + Assert.True(!view.IsPartial); + } + + [Fact] + public void GetView_SetsRazorPage() + { + // Arrange + var factory = new RazorViewFactory( + Mock.Of(), + Mock.Of(), + Mock.Of()); + + var page = Mock.Of(); + + // Act + var view = factory.GetView(page, isPartial: false) as RazorView; + + // Assert + Assert.NotNull(view); + Assert.Same(view.RazorPage, page); + } + [Fact] public void GetView_ReturnsRazorView() { @@ -24,71 +64,11 @@ namespace Microsoft.AspNet.Mvc.Razor.Test Mock.Of()); // Act - var view = factory.GetView(Mock.Of(), true); + var view = factory.GetView(Mock.Of(), isPartial: true); // Assert Assert.IsType(view); } - [Fact] - public async Task RenderAsync_ContextualizeMustBeInvoked() - { - // Arrange - var page = new TestableRazorPage(v => { }); - - var factory = new RazorViewFactory( - Mock.Of(), - Mock.Of(), - CreateViewStartProvider()); - - // Act - var view = factory.GetView(page, true); - - // Assert - var viewContext = CreateViewContext(view); - await Assert.DoesNotThrowAsync(() => view.RenderAsync(viewContext)); - } - - private static IViewStartProvider CreateViewStartProvider() - { - var viewStartPages = new IRazorPage[0]; - var viewStartProvider = new Mock(); - viewStartProvider.Setup(v => v.GetViewStartPages(It.IsAny())) - .Returns(viewStartPages); - - return viewStartProvider.Object; - } - - private static ViewContext CreateViewContext(IView view) - { - var httpContext = new DefaultHttpContext(); - var actionContext = new ActionContext(httpContext, routeData: null, actionDescriptor: null); - return new ViewContext( - actionContext, - view, - new ViewDataDictionary(new EmptyModelMetadataProvider()), - new StringWriter()); - } - - private class TestableRazorPage : RazorPage - { - private readonly Action _executeAction; - - public TestableRazorPage(Action executeAction) - { - _executeAction = executeAction; - } - - public void RenderBodyPublic() - { - Write(RenderBody()); - } - - public override Task ExecuteAsync() - { - _executeAction(this); - return Task.FromResult(0); - } - } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewTest.cs b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewTest.cs index fb732b415d..dd18c4993d 100644 --- a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewTest.cs +++ b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewTest.cs @@ -18,23 +18,6 @@ namespace Microsoft.AspNet.Mvc.Razor private const string LayoutPath = "~/Shared/_Layout.cshtml"; private readonly RenderAsyncDelegate _nullRenderAsyncDelegate = async writer => { }; - [Fact] - public async Task RenderAsync_ThrowsIfContextualizeHasNotBeenInvoked() - { - // Arrange - var page = new TestableRazorPage(v => { }); - var view = new RazorView(Mock.Of(), - Mock.Of(), - CreateViewStartProvider()); - var viewContext = CreateViewContext(view); - var expected = viewContext.Writer; - - // Act and Assert - var ex = await Assert.ThrowsAsync(() => view.RenderAsync(viewContext)); - Assert.Equal("The 'Contextualize' method must be called before 'RenderAsync' can be invoked.", - ex.Message); - } - [Fact] public async Task RenderAsync_AsPartial_DoesNotBufferOutput() { @@ -47,8 +30,9 @@ namespace Microsoft.AspNet.Mvc.Razor }); var view = new RazorView(Mock.Of(), Mock.Of(), - CreateViewStartProvider()); - view.Contextualize(page, isPartial: true); + CreateViewStartProvider(), + page, + isPartial: true); var viewContext = CreateViewContext(view); var expected = viewContext.Writer; @@ -71,11 +55,12 @@ namespace Microsoft.AspNet.Mvc.Razor Assert.Same(viewData, v.ViewContext.ViewData); }); var activator = new Mock(); - var view = new RazorView(Mock.Of(), activator.Object, - CreateViewStartProvider()); - view.Contextualize(page, isPartial: true); + CreateViewStartProvider(), + page, + isPartial: true); + var viewContext = CreateViewContext(view); var expectedWriter = viewContext.Writer; activator.Setup(a => a.Activate(page, It.IsAny())) @@ -104,8 +89,9 @@ namespace Microsoft.AspNet.Mvc.Razor .Verifiable(); var view = new RazorView(Mock.Of(), activator.Object, - CreateViewStartProvider()); - view.Contextualize(page, isPartial: true); + CreateViewStartProvider(), + page, + isPartial: true); var viewContext = CreateViewContext(view); // Act @@ -126,8 +112,9 @@ namespace Microsoft.AspNet.Mvc.Razor var viewStartProvider = CreateViewStartProvider(); var view = new RazorView(pageFactory.Object, Mock.Of(), - viewStartProvider); - view.Contextualize(page, isPartial: true); + viewStartProvider, + page, + isPartial: true); var viewContext = CreateViewContext(view); // Act @@ -150,8 +137,9 @@ namespace Microsoft.AspNet.Mvc.Razor }); var view = new RazorView(Mock.Of(), Mock.Of(), - CreateViewStartProvider()); - view.Contextualize(page, isPartial: false); + CreateViewStartProvider(), + page, + isPartial: false); var viewContext = CreateViewContext(view); var original = viewContext.Writer; @@ -173,8 +161,9 @@ namespace Microsoft.AspNet.Mvc.Razor }); var view = new RazorView(Mock.Of(), Mock.Of(), - CreateViewStartProvider()); - view.Contextualize(page, isPartial: false); + CreateViewStartProvider(), + page, + isPartial: false); var viewContext = CreateViewContext(view); var original = viewContext.Writer; @@ -198,9 +187,9 @@ namespace Microsoft.AspNet.Mvc.Razor .Verifiable(); var view = new RazorView(Mock.Of(), activator.Object, - CreateViewStartProvider()); - view.Contextualize(page, isPartial: false); - + CreateViewStartProvider(), + page, + isPartial: false); var viewContext = CreateViewContext(view); // Act @@ -240,8 +229,9 @@ namespace Microsoft.AspNet.Mvc.Razor .Verifiable(); var view = new RazorView(Mock.Of(), activator.Object, - CreateViewStartProvider(viewStart1, viewStart2)); - view.Contextualize(page, isPartial: false); + CreateViewStartProvider(viewStart1, viewStart2), + page, + isPartial: false); var viewContext = CreateViewContext(view); // Act @@ -294,8 +284,9 @@ foot-content"; var view = new RazorView(pageFactory.Object, activator.Object, - CreateViewStartProvider()); - view.Contextualize(page, isPartial: false); + CreateViewStartProvider(), + page, + isPartial: false); var viewContext = CreateViewContext(view); // Act @@ -327,8 +318,9 @@ foot-content"; var view = new RazorView(pageFactory.Object, Mock.Of(), - CreateViewStartProvider()); - view.Contextualize(page, isPartial: false); + CreateViewStartProvider(), + page, + isPartial: false); var viewContext = CreateViewContext(view); // Act and Assert @@ -353,8 +345,9 @@ foot-content"; var view = new RazorView(pageFactory.Object, Mock.Of(), - CreateViewStartProvider()); - view.Contextualize(page, isPartial: false); + CreateViewStartProvider(), + page, + isPartial: false); var viewContext = CreateViewContext(view); // Act and Assert @@ -404,8 +397,9 @@ body-content"; var view = new RazorView(pageFactory.Object, Mock.Of(), - CreateViewStartProvider()); - view.Contextualize(page, isPartial: false); + CreateViewStartProvider(), + page, + isPartial: false); var viewContext = CreateViewContext(view); // Act @@ -450,8 +444,9 @@ section-content-2"; var view = new RazorView(pageFactory.Object, Mock.Of(), - CreateViewStartProvider()); - view.Contextualize(page, isPartial: false); + CreateViewStartProvider(), + page, + isPartial: false); var viewContext = CreateViewContext(view); // Act @@ -494,8 +489,9 @@ section-content-2"; var view = new RazorView(pageFactory.Object, Mock.Of(), - CreateViewStartProvider()); - view.Contextualize(page, isPartial: false); + CreateViewStartProvider(), + page, + isPartial: false); var viewContext = CreateViewContext(view); // Act @@ -520,8 +516,9 @@ section-content-2"; var view = new RazorView(Mock.Of(), Mock.Of(), - CreateViewStartProvider()); - view.Contextualize(page, isPartial: false); + CreateViewStartProvider(), + page, + isPartial: false); var viewContext = CreateViewContext(view); // Act and Assert @@ -558,8 +555,9 @@ section-content-2"; var view = new RazorView(pageFactory.Object, Mock.Of(), - CreateViewStartProvider()); - view.Contextualize(page, isPartial: false); + CreateViewStartProvider(), + page, + isPartial: false); var viewContext = CreateViewContext(view); // Act and Assert @@ -630,8 +628,9 @@ section-content-2"; .Verifiable(); var view = new RazorView(pageFactory.Object, Mock.Of(), - viewStartProvider.Object); - view.Contextualize(page, isPartial: false); + viewStartProvider.Object, + page, + isPartial: false); var viewContext = CreateViewContext(view); viewContext.HttpContext.SetFeature(feature.Object); @@ -673,8 +672,9 @@ section-content-2"; var view = new RazorView(Mock.Of(), Mock.Of(), - Mock.Of()); - view.Contextualize(page, isPartial: true); + Mock.Of(), + page, + isPartial: true); var viewContext = CreateViewContext(view); viewContext.Writer = writer; viewContext.HttpContext.SetFeature(feature.Object); @@ -703,8 +703,9 @@ section-content-2"; var view = new RazorView(Mock.Of(), Mock.Of(), - Mock.Of()); - view.Contextualize(page, isPartial); + Mock.Of(), + page, + isPartial); var viewContext = CreateViewContext(view); // Act @@ -741,8 +742,9 @@ section-content-2"; var view = new RazorView(pageFactory, Mock.Of(), - CreateViewStartProvider(viewStart1, viewStart2)); - view.Contextualize(page, isPartial: false); + CreateViewStartProvider(viewStart1, viewStart2), + page, + isPartial: false); var viewContext = CreateViewContext(view); // Act @@ -777,8 +779,9 @@ section-content-2"; var view = new RazorView(pageFactory, Mock.Of(), - CreateViewStartProvider(viewStart1, viewStart2)); - view.Contextualize(page, isPartial: false); + CreateViewStartProvider(viewStart1, viewStart2), + page, + isPartial: false); var viewContext = CreateViewContext(view); // Act @@ -816,8 +819,9 @@ section-content-2"; var view = new RazorView(pageFactory.Object, Mock.Of(), - CreateViewStartProvider(viewStart)); - view.Contextualize(page, isPartial: false); + CreateViewStartProvider(viewStart), + page, + isPartial: false); var viewContext = CreateViewContext(view); // Act @@ -840,8 +844,9 @@ section-content-2"; }); var view = new RazorView(Mock.Of(), Mock.Of(), - CreateViewStartProvider()); - view.Contextualize(page, isPartial: true); + CreateViewStartProvider(), + page, + isPartial: true); var viewContext = CreateViewContext(view); // Act