public IEnumerable <IDocument> Execute(IReadOnlyList <IDocument> inputs, IExecutionContext context) { IRazorPageFactory pageFactory = new VirtualPathRazorPageFactory(context.InputFolder, context, _basePageType); List <IDocument> validInputs = inputs .Where(x => _ignorePrefix == null || !x.ContainsKey(Keys.SourceFileName) || !x.String(Keys.SourceFileName).StartsWith(_ignorePrefix)) .ToList(); // Compile the pages in parallel ConcurrentDictionary <IDocument, Tuple <ViewContext, ViewEngineResult> > compilationResults = new ConcurrentDictionary <IDocument, Tuple <ViewContext, ViewEngineResult> >(); Parallel.ForEach(validInputs, x => { context.Trace.Verbose("Compiling Razor for {0}", x.Source); IViewStartProvider viewStartProvider = new ViewStartProvider(pageFactory, _viewStartPath?.Invoke <string>(x, context)); IRazorViewFactory viewFactory = new RazorViewFactory(viewStartProvider); IRazorViewEngine viewEngine = new RazorViewEngine(pageFactory, viewFactory); ViewContext viewContext = new ViewContext(null, new ViewDataDictionary(), null, x.Metadata, context, viewEngine); ViewEngineResult viewEngineResult; using (Stream stream = x.GetStream()) { viewEngineResult = viewEngine.GetView(viewContext, GetRelativePath(x), stream).EnsureSuccessful(); } compilationResults[x] = new Tuple <ViewContext, ViewEngineResult>(viewContext, viewEngineResult); }); // Now evaluate them in sequence - have to do this because BufferedHtmlContent doesn't appear to work well in multi-threaded parallel execution TaskScheduler exclusiveScheduler = new ConcurrentExclusiveSchedulerPair().ExclusiveScheduler; CancellationToken cancellationToken = new CancellationToken(); return(validInputs .Select(x => { using (context.Trace.WithIndent().Verbose("Processing Razor for {0}", x.Source)) { Tuple <ViewContext, ViewEngineResult> compilationResult; if (compilationResults.TryGetValue(x, out compilationResult)) { using (StringWriter writer = new StringWriter()) { compilationResult.Item1.View = compilationResult.Item2.View; compilationResult.Item1.Writer = writer; Task.Factory.StartNew(() => compilationResult.Item2.View.RenderAsync(compilationResult.Item1), cancellationToken, TaskCreationOptions.None, exclusiveScheduler).Unwrap().GetAwaiter().GetResult(); return x.Clone(writer.ToString()); } } context.Trace.Warning("Could not find compilation result for {0}", x.Source); return null; } })); }
public void GetViewStartLocations_ReturnsEmptySequenceIfViewPathIsEmpty(string viewPath) { // Arrange var appPath = @"x:\test"; var provider = new ViewStartProvider(GetAppEnv(appPath), Mock.Of<IRazorPageFactory>()); // Act var result = provider.GetViewStartLocations(viewPath); // Assert Assert.Empty(result); }
public void GetViewStartLocations_ReturnsEmptySequenceIfViewPathIsEmpty(string viewPath) { // Arrange var appPath = @"x:\test"; var provider = new ViewStartProvider(GetAppEnv(appPath), Mock.Of <IRazorPageFactory>()); // Act var result = provider.GetViewStartLocations(viewPath); // Assert Assert.Empty(result); }
public void GetViewStartLocations_ReturnsPotentialViewStartLocations(string appPath, string viewPath, IEnumerable<string> expected) { // Arrange var provider = new ViewStartProvider(GetAppEnv(appPath), Mock.Of<IRazorPageFactory>()); // Act var result = provider.GetViewStartLocations(viewPath); // Assert Assert.Equal(expected, result); }
public void GetViewStartLocations_ReturnsPotentialViewStartLocations(string appPath, string viewPath, IEnumerable <string> expected) { // Arrange var provider = new ViewStartProvider(GetAppEnv(appPath), Mock.Of <IRazorPageFactory>()); // Act var result = provider.GetViewStartLocations(viewPath); // Assert Assert.Equal(expected, result); }