Modify RazorView to be instantiated via TypeActivator

Partial fix for #889
This commit is contained in:
Pranav K 2014-08-01 10:37:06 -07:00
parent 9e68a163fd
commit 90b40832ff
5 changed files with 70 additions and 48 deletions

View File

@ -25,7 +25,7 @@ namespace Microsoft.AspNet.Mvc.Razor
Action<TextWriter> RenderBodyDelegate { get; set; } Action<TextWriter> RenderBodyDelegate { get; set; }
/// <summary> /// <summary>
/// Gets the path to the page. /// Gets the application base relative path to the page.
/// </summary> /// </summary>
string Path { get; set; } string Path { get; set; }

View File

@ -17,33 +17,34 @@ namespace Microsoft.AspNet.Mvc.Razor
private readonly IRazorPageActivator _pageActivator; private readonly IRazorPageActivator _pageActivator;
private readonly IViewStartProvider _viewStartProvider; private readonly IViewStartProvider _viewStartProvider;
private readonly IRazorPage _page; private readonly IRazorPage _page;
private readonly bool _executeViewHierarchy;
/// <summary> /// <summary>
/// Initializes a new instance of RazorView /// Initializes a new instance of RazorView
/// </summary> /// </summary>
/// <param name="page">The page to execute</param> /// <param name="page">The page to execute</param>
/// <param name="pageFactory">The view factory used to instantiate additional views.</param> /// <param name="pageFactory">The view factory used to instantiate layout and _ViewStart pages.</param>
/// <param name="pageActivator">The <see cref="IRazorPageActivator"/> used to activate pages.</param> /// <param name="pageActivator">The <see cref="IRazorPageActivator"/> used to activate pages.</param>
/// <param name="executeViewHierarchy">A value that indiciates whether the view hierarchy that involves
/// view start and layout pages are executed as part of the executing the page.</param>
public RazorView([NotNull] IRazorPageFactory pageFactory, public RazorView([NotNull] IRazorPageFactory pageFactory,
[NotNull] IRazorPageActivator pageActivator, [NotNull] IRazorPageActivator pageActivator,
[NotNull] IViewStartProvider viewStartProvider, [NotNull] IViewStartProvider viewStartProvider,
[NotNull] IRazorPage page, [NotNull] IRazorPage page)
bool executeViewHierarchy)
{ {
_pageFactory = pageFactory; _pageFactory = pageFactory;
_pageActivator = pageActivator; _pageActivator = pageActivator;
_viewStartProvider = viewStartProvider; _viewStartProvider = viewStartProvider;
_page = page; _page = page;
_executeViewHierarchy = executeViewHierarchy;
} }
/// <summary>
/// Gets or sets a value that determines if the view hierarchy is executed as part of
/// executing the <see cref="IRazorPage"/> instance. The view hierarchy involves _ViewStart
/// and Layout pages.</param>
public bool ExecuteViewHierarchy { get; set; }
/// <inheritdoc /> /// <inheritdoc />
public async Task RenderAsync([NotNull] ViewContext context) public async Task RenderAsync([NotNull] ViewContext context)
{ {
if (_executeViewHierarchy) if (ExecuteViewHierarchy)
{ {
var bodyWriter = await RenderPageAsync(_page, context, executeViewStart: true); var bodyWriter = await RenderPageAsync(_page, context, executeViewStart: true);
await RenderLayoutAsync(context, bodyWriter); await RenderLayoutAsync(context, bodyWriter);

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using Microsoft.AspNet.Mvc.Rendering; using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.Framework.DependencyInjection;
namespace Microsoft.AspNet.Mvc.Razor namespace Microsoft.AspNet.Mvc.Razor
{ {
@ -30,8 +31,8 @@ namespace Microsoft.AspNet.Mvc.Razor
}; };
private readonly IRazorPageFactory _pageFactory; private readonly IRazorPageFactory _pageFactory;
private readonly IRazorPageActivator _pageActivator; private readonly ITypeActivator _typeActivator;
private readonly IViewStartProvider _viewStartProvider; private readonly IServiceProvider _serviceProvider;
/// <summary> /// <summary>
/// Initializes a new instance of the RazorViewEngine class. /// Initializes a new instance of the RazorViewEngine class.
@ -41,12 +42,12 @@ namespace Microsoft.AspNet.Mvc.Razor
/// <param name="viewStartProvider">The provider used to provide instances of ViewStarts applicable to the /// <param name="viewStartProvider">The provider used to provide instances of ViewStarts applicable to the
/// page being rendered.</param> /// page being rendered.</param>
public RazorViewEngine(IRazorPageFactory pageFactory, public RazorViewEngine(IRazorPageFactory pageFactory,
IRazorPageActivator pageActivator, ITypeActivator typeActivator,
IViewStartProvider viewStartProvider) IServiceProvider serviceProvider)
{ {
_pageFactory = pageFactory; _pageFactory = pageFactory;
_pageActivator = pageActivator; _typeActivator = typeActivator;
_viewStartProvider = viewStartProvider; _serviceProvider = serviceProvider;
} }
public IEnumerable<string> ViewLocationFormats public IEnumerable<string> ViewLocationFormats
@ -110,11 +111,8 @@ namespace Microsoft.AspNet.Mvc.Razor
private ViewEngineResult CreateFoundResult(IRazorPage page, string viewName, bool partial) private ViewEngineResult CreateFoundResult(IRazorPage page, string viewName, bool partial)
{ {
var view = new RazorView(_pageFactory, var view = _typeActivator.CreateInstance<RazorView>(_serviceProvider, page);
_pageActivator, view.ExecuteViewHierarchy = !partial;
_viewStartProvider,
page,
executeViewHierarchy: !partial);
return ViewEngineResult.Found(viewName, view); return ViewEngineResult.Found(viewName, view);
} }

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using Microsoft.AspNet.Http; using Microsoft.AspNet.Http;
using Microsoft.AspNet.Mvc.Rendering; using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Routing; using Microsoft.AspNet.Routing;
using Microsoft.Framework.DependencyInjection;
using Moq; using Moq;
using Xunit; using Xunit;
@ -175,11 +176,20 @@ namespace Microsoft.AspNet.Mvc.Razor.Test
{ {
// Arrange // Arrange
var pageFactory = new Mock<IRazorPageFactory>(); var pageFactory = new Mock<IRazorPageFactory>();
var page = Mock.Of<IRazorPage>();
pageFactory.Setup(p => p.CreateInstance(It.IsAny<string>())) pageFactory.Setup(p => p.CreateInstance(It.IsAny<string>()))
.Returns(Mock.Of<IRazorPage>()); .Returns(Mock.Of<IRazorPage>());
var serviceProvider = new Mock<IServiceProvider>();
serviceProvider.Setup(p => p.GetService(typeof(IRazorPageFactory)))
.Returns(pageFactory.Object);
serviceProvider.Setup(p => p.GetService(typeof(IRazorPageActivator)))
.Returns(Mock.Of<IRazorPageActivator>());
serviceProvider.Setup(p => p.GetService(typeof(IViewStartProvider)))
.Returns(Mock.Of<IViewStartProvider>());
var viewEngine = new RazorViewEngine(pageFactory.Object, var viewEngine = new RazorViewEngine(pageFactory.Object,
Mock.Of<IRazorPageActivator>(), new TypeActivator(),
Mock.Of<IViewStartProvider>()); serviceProvider.Object);
var context = GetActionContext(_controllerTestContext); var context = GetActionContext(_controllerTestContext);
// Act // Act
@ -198,8 +208,8 @@ namespace Microsoft.AspNet.Mvc.Razor.Test
.Returns<RazorPage>(null); .Returns<RazorPage>(null);
var viewEngine = new RazorViewEngine(pageFactory.Object, var viewEngine = new RazorViewEngine(pageFactory.Object,
Mock.Of<IRazorPageActivator>(), Mock.Of<ITypeActivator>(),
Mock.Of<IViewStartProvider>()); Mock.Of<IServiceProvider>());
return viewEngine; return viewEngine;
} }

View File

@ -28,8 +28,7 @@ namespace Microsoft.AspNet.Mvc.Razor
var view = new RazorView(Mock.Of<IRazorPageFactory>(), var view = new RazorView(Mock.Of<IRazorPageFactory>(),
Mock.Of<IRazorPageActivator>(), Mock.Of<IRazorPageActivator>(),
CreateViewStartProvider(), CreateViewStartProvider(),
page, page);
executeViewHierarchy: false);
var viewContext = CreateViewContext(view); var viewContext = CreateViewContext(view);
var expected = viewContext.Writer; var expected = viewContext.Writer;
@ -56,8 +55,7 @@ namespace Microsoft.AspNet.Mvc.Razor
var view = new RazorView(Mock.Of<IRazorPageFactory>(), var view = new RazorView(Mock.Of<IRazorPageFactory>(),
activator.Object, activator.Object,
CreateViewStartProvider(), CreateViewStartProvider(),
page, page);
executeViewHierarchy: false);
var viewContext = CreateViewContext(view); var viewContext = CreateViewContext(view);
var expectedWriter = viewContext.Writer; var expectedWriter = viewContext.Writer;
activator.Setup(a => a.Activate(page, It.IsAny<ViewContext>())) activator.Setup(a => a.Activate(page, It.IsAny<ViewContext>()))
@ -87,8 +85,7 @@ namespace Microsoft.AspNet.Mvc.Razor
var view = new RazorView(Mock.Of<IRazorPageFactory>(), var view = new RazorView(Mock.Of<IRazorPageFactory>(),
activator.Object, activator.Object,
CreateViewStartProvider(), CreateViewStartProvider(),
page, page);
executeViewHierarchy: false);
var viewContext = CreateViewContext(view); var viewContext = CreateViewContext(view);
// Act // Act
@ -110,8 +107,7 @@ namespace Microsoft.AspNet.Mvc.Razor
var view = new RazorView(pageFactory.Object, var view = new RazorView(pageFactory.Object,
Mock.Of<IRazorPageActivator>(), Mock.Of<IRazorPageActivator>(),
viewStartProvider, viewStartProvider,
page, page);
executeViewHierarchy: false);
var viewContext = CreateViewContext(view); var viewContext = CreateViewContext(view);
// Act // Act
@ -134,8 +130,10 @@ namespace Microsoft.AspNet.Mvc.Razor
var view = new RazorView(Mock.Of<IRazorPageFactory>(), var view = new RazorView(Mock.Of<IRazorPageFactory>(),
Mock.Of<IRazorPageActivator>(), Mock.Of<IRazorPageActivator>(),
CreateViewStartProvider(), CreateViewStartProvider(),
page, page)
executeViewHierarchy: true); {
ExecuteViewHierarchy = true
};
var viewContext = CreateViewContext(view); var viewContext = CreateViewContext(view);
var original = viewContext.Writer; var original = viewContext.Writer;
@ -158,8 +156,10 @@ namespace Microsoft.AspNet.Mvc.Razor
var view = new RazorView(Mock.Of<IRazorPageFactory>(), var view = new RazorView(Mock.Of<IRazorPageFactory>(),
Mock.Of<IRazorPageActivator>(), Mock.Of<IRazorPageActivator>(),
CreateViewStartProvider(), CreateViewStartProvider(),
page, page)
executeViewHierarchy: true); {
ExecuteViewHierarchy = true
};
var viewContext = CreateViewContext(view); var viewContext = CreateViewContext(view);
var original = viewContext.Writer; var original = viewContext.Writer;
@ -184,8 +184,11 @@ namespace Microsoft.AspNet.Mvc.Razor
var view = new RazorView(Mock.Of<IRazorPageFactory>(), var view = new RazorView(Mock.Of<IRazorPageFactory>(),
activator.Object, activator.Object,
CreateViewStartProvider(), CreateViewStartProvider(),
page, page)
executeViewHierarchy: true); {
ExecuteViewHierarchy = true
};
var viewContext = CreateViewContext(view); var viewContext = CreateViewContext(view);
// Act // Act
@ -226,8 +229,10 @@ namespace Microsoft.AspNet.Mvc.Razor
var view = new RazorView(Mock.Of<IRazorPageFactory>(), var view = new RazorView(Mock.Of<IRazorPageFactory>(),
activator.Object, activator.Object,
CreateViewStartProvider(viewStart1, viewStart2), CreateViewStartProvider(viewStart1, viewStart2),
page, page)
executeViewHierarchy: true); {
ExecuteViewHierarchy = true
};
var viewContext = CreateViewContext(view); var viewContext = CreateViewContext(view);
// Act // Act
@ -281,8 +286,10 @@ foot-content";
var view = new RazorView(pageFactory.Object, var view = new RazorView(pageFactory.Object,
activator.Object, activator.Object,
CreateViewStartProvider(), CreateViewStartProvider(),
page, page)
executeViewHierarchy: true); {
ExecuteViewHierarchy = true
};
var viewContext = CreateViewContext(view); var viewContext = CreateViewContext(view);
// Act // Act
@ -315,8 +322,10 @@ foot-content";
var view = new RazorView(pageFactory.Object, var view = new RazorView(pageFactory.Object,
Mock.Of<IRazorPageActivator>(), Mock.Of<IRazorPageActivator>(),
CreateViewStartProvider(), CreateViewStartProvider(),
page, page)
executeViewHierarchy: true); {
ExecuteViewHierarchy = true
};
var viewContext = CreateViewContext(view); var viewContext = CreateViewContext(view);
// Act and Assert // Act and Assert
@ -342,8 +351,10 @@ foot-content";
var view = new RazorView(pageFactory.Object, var view = new RazorView(pageFactory.Object,
Mock.Of<IRazorPageActivator>(), Mock.Of<IRazorPageActivator>(),
CreateViewStartProvider(), CreateViewStartProvider(),
page, page)
executeViewHierarchy: true); {
ExecuteViewHierarchy = true
};
var viewContext = CreateViewContext(view); var viewContext = CreateViewContext(view);
// Act and Assert // Act and Assert
@ -397,8 +408,10 @@ body-content";
var view = new RazorView(pageFactory.Object, var view = new RazorView(pageFactory.Object,
Mock.Of<IRazorPageActivator>(), Mock.Of<IRazorPageActivator>(),
CreateViewStartProvider(), CreateViewStartProvider(),
page, page)
executeViewHierarchy: true); {
ExecuteViewHierarchy = true
};
var viewContext = CreateViewContext(view); var viewContext = CreateViewContext(view);
// Act // Act