Пример #1
0
        public IEnumerable<IDocument> Execute(IReadOnlyList<IDocument> inputs, IExecutionContext context)
        {
            IRazorPageFactory pageFactory = new VirtualPathRazorPageFactory(context.InputFolder, context, _basePageType);
            IViewStartProvider viewStartProvider = new ViewStartProvider(pageFactory);
            IRazorViewFactory viewFactory = new RazorViewFactory(viewStartProvider);
            IRazorViewEngine viewEngine = new RazorViewEngine(pageFactory, viewFactory);

            return inputs.Select(x =>
            {
                ViewContext viewContext = new ViewContext(null, new ViewDataDictionary(), null, x.Metadata, context, viewEngine);
                string relativePath = "/";
                if (x.ContainsKey(MetadataKeys.RelativeFilePath))
                {
                    relativePath += x.String(MetadataKeys.RelativeFilePath);
                }
                ViewEngineResult viewEngineResult = viewEngine.GetView(viewContext, relativePath, x.Content).EnsureSuccessful();
                using (StringWriter writer = new StringWriter())
                {
                    viewContext.View = viewEngineResult.View;
                    viewContext.Writer = writer;
                    AsyncHelper.RunSync(() => viewEngineResult.View.RenderAsync(viewContext));
                    return x.Clone(writer.ToString());
                }
            });
        }
Пример #2
0
        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 =>
            {
                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, 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(input =>
                {
                    using (Trace.WithIndent().Verbose("Processing Razor for {0}", input.Source))
                    {
                        Tuple<ViewContext, ViewEngineResult> compilationResult;
                        if (compilationResults.TryGetValue(input, 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 context.GetDocument(input, writer.ToString());
                            }
                        }
                        Trace.Warning("Could not find compilation result for {0}", input.Source);
                        return null;
                    }
                });
        }