Beispiel #1
0
        public void PopulateFeature_PrefersViewsFromPartsWithHigherPrecedence()
        {
            // Arrange
            var part1 = new AssemblyPart(typeof(ViewsFeatureProvider).Assembly);
            var item1 = new TestRazorCompiledItem(typeof(StringBuilder), "mvc.1.0.view", "/Areas/Admin/Views/Shared/_Layout.cshtml", new object[] { });

            var part2 = new AssemblyPart(GetType().Assembly);
            var item2 = new TestRazorCompiledItem(typeof(string), "mvc.1.0.view", "/Areas/Admin/Views/Shared/_Layout.cshtml", new object[] { });
            var item3 = new TestRazorCompiledItem(typeof(string), "mvc.1.0.view", "/Areas/Admin/Views/Shared/_Partial.cshtml", new object[] { });

            var items = new Dictionary <AssemblyPart, IReadOnlyList <RazorCompiledItem> >
            {
                { part1, new[] { item1 } },
                { part2, new[] { item2, item3, } },
            };

            var featureProvider = new TestableViewsFeatureProvider(items, attributes: new Dictionary <AssemblyPart, IEnumerable <RazorViewAttribute> >());
            var partManager     = new ApplicationPartManager();

            partManager.ApplicationParts.Add(part1);
            partManager.ApplicationParts.Add(part2);
            partManager.FeatureProviders.Add(featureProvider);
            var feature = new ViewsFeature();

            // Act
            partManager.PopulateFeature(feature);

            // Assert
            Assert.Collection(feature.ViewDescriptors.OrderBy(f => f.RelativePath, StringComparer.Ordinal),
                              view => Assert.Same(item1, view.Item),
                              view => Assert.Same(item3, view.Item));
        }
 public void PopulateFeature(IEnumerable <ApplicationPart> parts, ViewsFeature feature)
 {
     foreach (var item in CompiledViews)
     {
         feature.ViewDescriptors.Add(item);
     }
 }
Beispiel #3
0
        public void PopulateFeature_ThrowsIfSingleAssemblyContainsMultipleAttributesWithTheSamePath()
        {
            // Arrange
            var path1    = "/Views/test/Index.cshtml";
            var path2    = "/views/test/index.cshtml";
            var expected = string.Join(
                Environment.NewLine,
                "The following precompiled view paths differ only in case, which is not supported:",
                path1,
                path2);
            var part            = new AssemblyPart(typeof(object).GetTypeInfo().Assembly);
            var featureProvider = new TestableViewsFeatureProvider(new Dictionary <AssemblyPart, IEnumerable <RazorViewAttribute> >
            {
                {
                    part,
                    new[]
                    {
                        new RazorViewAttribute(path1, typeof(object)),
                        new RazorViewAttribute(path2, typeof(object)),
                    }
                },
            });

            var applicationPartManager = new ApplicationPartManager();

            applicationPartManager.ApplicationParts.Add(part);
            applicationPartManager.FeatureProviders.Add(featureProvider);
            var feature = new ViewsFeature();

            // Act & Assert
            var ex = Assert.Throws <InvalidOperationException>(() => applicationPartManager.PopulateFeature(feature));

            Assert.Equal(expected, ex.Message);
        }
Beispiel #4
0
        public DefaultViewCompilerProvider(
            ApplicationPartManager applicationPartManager,
            ILoggerFactory loggerFactory)
        {
            var feature = new ViewsFeature();

            applicationPartManager.PopulateFeature(feature);

            _compiler = new DefaultViewCompiler(feature.ViewDescriptors, loggerFactory.CreateLogger <DefaultViewCompiler>());
        }
        public void PopulateFeature_ReturnsViewsFromAllAvailableApplicationParts()
        {
            // Arrange
            var part1           = new AssemblyPart(typeof(object).GetTypeInfo().Assembly);
            var part2           = new AssemblyPart(GetType().GetTypeInfo().Assembly);
            var featureProvider = new TestableViewsFeatureProvider(new Dictionary <AssemblyPart, IEnumerable <RazorViewAttribute> >
            {
                {
                    part1,
                    new[]
                    {
                        new RazorViewAttribute("/Views/test/Index.cshtml", typeof(object)),
                    }
                },
                {
                    part2,
                    new[]
                    {
                        new RazorViewAttribute("/Areas/Admin/Views/Index.cshtml", typeof(string)),
                        new RazorViewAttribute("/Areas/Admin/Views/About.cshtml", typeof(int)),
                    }
                },
            });

            var applicationPartManager = new ApplicationPartManager();

            applicationPartManager.ApplicationParts.Add(part1);
            applicationPartManager.ApplicationParts.Add(part2);
            applicationPartManager.FeatureProviders.Add(featureProvider);
            var feature = new ViewsFeature();

            // Act
            applicationPartManager.PopulateFeature(feature);

            // Assert
            Assert.Collection(feature.ViewDescriptors.OrderBy(f => f.RelativePath, StringComparer.Ordinal),
                              view =>
            {
                Assert.Equal("/Areas/Admin/Views/About.cshtml", view.RelativePath);
                Assert.Equal(typeof(int), view.ViewAttribute.ViewType);
            },
                              view =>
            {
                Assert.Equal("/Areas/Admin/Views/Index.cshtml", view.RelativePath);
                Assert.Equal(typeof(string), view.ViewAttribute.ViewType);
            },
                              view =>
            {
                Assert.Equal("/Views/test/Index.cshtml", view.RelativePath);
                Assert.Equal(typeof(object), view.ViewAttribute.ViewType);
            });
        }
Beispiel #6
0
        public void PopulateFeature_ReturnsEmptySequenceIfNoAssemblyPartHasViewAssembly()
        {
            // Arrange
            var partManager = new ApplicationPartManager();

            partManager.ApplicationParts.Add(new AssemblyPart(typeof(ViewsFeatureProviderTest).Assembly));
            partManager.FeatureProviders.Add(new ViewsFeatureProvider());
            var feature = new ViewsFeature();

            // Act
            partManager.PopulateFeature(feature);

            // Assert
            Assert.Empty(feature.ViewDescriptors);
        }
        public void PopulateFeature_DoesNotFail_IfAssemblyHasEmptyLocation()
        {
            // Arrange
            var assembly = new AssemblyWithEmptyLocation();
            var applicationPartManager = new ApplicationPartManager();

            applicationPartManager.ApplicationParts.Add(new AssemblyPart(assembly));
            applicationPartManager.FeatureProviders.Add(new ViewsFeatureProvider());
            var feature = new ViewsFeature();

            // Act
            applicationPartManager.PopulateFeature(feature);

            // Assert
            Assert.Empty(feature.ViewDescriptors);
        }
Beispiel #8
0
        public void PopulateFeature_ReturnsEmptySequenceIfNoDynamicAssemblyPartHasViewAssembly()
        {
            // Arrange
            var name     = new AssemblyName($"DynamicAssembly-{Guid.NewGuid()}");
            var assembly = AssemblyBuilder.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndCollect);

            var partManager = new ApplicationPartManager();

            partManager.ApplicationParts.Add(new AssemblyPart(assembly));
            partManager.FeatureProviders.Add(new ViewsFeatureProvider());
            var feature = new ViewsFeature();

            // Act
            partManager.PopulateFeature(feature);

            // Assert
            Assert.Empty(feature.ViewDescriptors);
        }
Beispiel #9
0
        public void PopulateFeature_PreservesOldBehavior_IfGetViewAttributesWasOverriden()
        {
            // Arrange
            var assembly = new AssemblyWithEmptyLocation(
                new RazorViewAttribute[] { new RazorViewAttribute("view", typeof(string)) },
                new RazorCompiledItemAttribute[] { });

            var partManager = new ApplicationPartManager();

            partManager.ApplicationParts.Add(new AssemblyPart(assembly));
            partManager.FeatureProviders.Add(new OverrideViewsFeatureProvider());
            var feature = new ViewsFeature();

            // Act
            partManager.PopulateFeature(feature);

            // Assert
            Assert.Empty(feature.ViewDescriptors);
        }
        private IViewCompiler CreateCompiler()
        {
            var feature = new ViewsFeature();

            _applicationPartManager.PopulateFeature(feature);

            return(new RazorViewCompiler(
                       _fileProviderAccessor.FileProvider,
                       _razorProjectEngine,
                       _csharpCompiler,
#pragma warning disable CS0618 // Type or member is obsolete
                       _viewEngineOptions.CompilationCallback,
#pragma warning restore CS0618 // Type or member is obsolete
                       feature.ViewDescriptors,
                       _compilationMemoryCacheProvider.CompilationMemoryCache,
                       _logger)
            {
                AllowRecompilingViewsOnFileChange = _viewEngineOptions.AllowRecompilingViewsOnFileChange,
            });
        }
Beispiel #11
0
        private void EnsureCompiledViews(ILogger logger)
        {
            if (_compiledViews is not null)
            {
                return;
            }

            var viewsFeature = new ViewsFeature();

            _applicationPartManager.PopulateFeature(viewsFeature);

            // We need to validate that the all compiled views are unique by path (case-insensitive).
            // We do this because there's no good way to canonicalize paths on windows, and it will create
            // problems when deploying to linux. Rather than deal with these issues, we just don't support
            // views that differ only by case.
            var compiledViews = new Dictionary <string, Task <CompiledViewDescriptor> >(
                viewsFeature.ViewDescriptors.Count,
                StringComparer.OrdinalIgnoreCase);

            foreach (var compiledView in viewsFeature.ViewDescriptors)
            {
                logger.ViewCompilerLocatedCompiledView(compiledView.RelativePath);

                if (!compiledViews.ContainsKey(compiledView.RelativePath))
                {
                    // View ordering has precedence semantics, a view with a higher precedence was not
                    // already added to the list.
                    compiledViews.TryAdd(compiledView.RelativePath, Task.FromResult(compiledView));
                }
            }

            if (compiledViews.Count == 0)
            {
                logger.ViewCompilerNoCompiledViewsFound();
            }

            // Safe races should be ok. We would end up logging multiple times
            // if this is invoked concurrently, but since this is primarily a dev-scenario, we don't think
            // this will happen often. We could always re-consider the logging if we get feedback.
            _compiledViews = compiledViews;
        }
        public void PopulateFeature_ReturnsViewsFromAllAvailableApplicationParts()
        {
            // Arrange
            var part1           = new AssemblyPart(typeof(object).GetTypeInfo().Assembly);
            var part2           = new AssemblyPart(GetType().GetTypeInfo().Assembly);
            var featureProvider = new TestableViewsFeatureProvider(new Dictionary <AssemblyPart, Type>
            {
                { part1, typeof(ViewInfoContainer1) },
                { part2, typeof(ViewInfoContainer2) },
            });

            var applicationPartManager = new ApplicationPartManager();

            applicationPartManager.ApplicationParts.Add(part1);
            applicationPartManager.ApplicationParts.Add(part2);
            applicationPartManager.FeatureProviders.Add(featureProvider);
            var feature = new ViewsFeature();

            // Act
            applicationPartManager.PopulateFeature(feature);

            // Assert
            Assert.Collection(feature.Views.OrderBy(f => f.Key, StringComparer.Ordinal),
                              view =>
            {
                Assert.Equal("/Areas/Admin/Views/About.cshtml", view.Key);
                Assert.Equal(typeof(int), view.Value);
            },
                              view =>
            {
                Assert.Equal("/Areas/Admin/Views/Index.cshtml", view.Key);
                Assert.Equal(typeof(string), view.Value);
            },
                              view =>
            {
                Assert.Equal("/Views/test/Index.cshtml", view.Key);
                Assert.Equal(typeof(object), view.Value);
            });
        }
Beispiel #13
0
        public void PopulateFeature_ReadsAttributesFromTheCurrentAssembly()
        {
            // Arrange
            var item1    = new RazorCompiledItemAttribute(typeof(string), "mvc.1.0.view", "view");
            var assembly = new AssemblyWithEmptyLocation(
                new RazorViewAttribute[] { new RazorViewAttribute("view", typeof(string)) },
                new RazorCompiledItemAttribute[] { item1 });

            var partManager = new ApplicationPartManager();

            partManager.ApplicationParts.Add(new AssemblyPart(assembly));
            partManager.FeatureProviders.Add(new ViewsFeatureProvider());
            var feature = new ViewsFeature();

            // Act
            partManager.PopulateFeature(feature);

            // Assert
            var descriptor = Assert.Single(feature.ViewDescriptors);

            Assert.Equal(typeof(string), descriptor.Item.Type);
            Assert.Equal("mvc.1.0.view", descriptor.Item.Kind);
            Assert.Equal("view", descriptor.Item.Identifier);
        }
Beispiel #14
0
        public void PopulateFeature_ReturnsViewsFromAllAvailableApplicationParts()
        {
            // Arrange
            var part1 = new AssemblyPart(typeof(object).Assembly);
            var part2 = new AssemblyPart(GetType().Assembly);

            var items = new Dictionary <AssemblyPart, IReadOnlyList <RazorCompiledItem> >
            {
                {
                    part1,
                    new[]
                    {
                        new TestRazorCompiledItem(typeof(object), "mvc.1.0.view", "/Views/test/Index.cshtml", new object[] { }),

                        // This one doesn't have a RazorViewAttribute
                        new TestRazorCompiledItem(typeof(StringBuilder), "mvc.1.0.view", "/Views/test/About.cshtml", new object[] { }),
                    }
                },
                {
                    part2,
                    new[]
                    {
                        new TestRazorCompiledItem(typeof(string), "mvc.1.0.view", "/Areas/Admin/Views/Index.cshtml", new object[] { }),
                    }
                },
            };

            var attributes = new Dictionary <AssemblyPart, IEnumerable <RazorViewAttribute> >
            {
                {
                    part1,
                    new[]
                    {
                        new RazorViewAttribute("/Views/test/Index.cshtml", typeof(object)),
                    }
                },
                {
                    part2,
                    new[]
                    {
                        new RazorViewAttribute("/Areas/Admin/Views/Index.cshtml", typeof(string)),

                        // This one doesn't have a RazorCompiledItem
                        new RazorViewAttribute("/Areas/Admin/Views/About.cshtml", typeof(int)),
                    }
                },
            };

            var featureProvider = new TestableViewsFeatureProvider(items, attributes);
            var partManager     = new ApplicationPartManager();

            partManager.ApplicationParts.Add(part1);
            partManager.ApplicationParts.Add(part2);
            partManager.FeatureProviders.Add(featureProvider);
            var feature = new ViewsFeature();

            // Act
            partManager.PopulateFeature(feature);

            // Assert
            Assert.Collection(feature.ViewDescriptors.OrderBy(f => f.RelativePath, StringComparer.Ordinal),
                              view =>
            {
                Assert.Empty(view.ExpirationTokens);
                Assert.True(view.IsPrecompiled);
                Assert.Null(view.Item);
                Assert.Equal("/Areas/Admin/Views/About.cshtml", view.RelativePath);
                Assert.Equal(typeof(int), view.Type);
                Assert.Equal("/Areas/Admin/Views/About.cshtml", view.ViewAttribute.Path);
                Assert.Equal(typeof(int), view.ViewAttribute.ViewType);
            },
                              view =>
            {
                // This one doesn't have a RazorCompiledItem
                Assert.Empty(view.ExpirationTokens);
                Assert.True(view.IsPrecompiled);
                Assert.Equal("/Areas/Admin/Views/Index.cshtml", view.Item.Identifier);
                Assert.Equal("mvc.1.0.view", view.Item.Kind);
                Assert.Equal(typeof(string), view.Item.Type);
                Assert.Equal("/Areas/Admin/Views/Index.cshtml", view.RelativePath);
                Assert.Equal(typeof(string), view.Type);
                Assert.Equal("/Areas/Admin/Views/Index.cshtml", view.ViewAttribute.Path);
                Assert.Equal(typeof(string), view.ViewAttribute.ViewType);
            },
                              view =>
            {
                // This one doesn't have a RazorViewAttribute
                Assert.Empty(view.ExpirationTokens);
                Assert.True(view.IsPrecompiled);
                Assert.Equal("/Views/test/About.cshtml", view.Item.Identifier);
                Assert.Equal("mvc.1.0.view", view.Item.Kind);
                Assert.Equal(typeof(StringBuilder), view.Item.Type);
                Assert.Equal("/Views/test/About.cshtml", view.RelativePath);
                Assert.Equal(typeof(StringBuilder), view.Type);
                Assert.Null(view.ViewAttribute);
            },
                              view =>
            {
                Assert.Empty(view.ExpirationTokens);
                Assert.True(view.IsPrecompiled);
                Assert.Equal("/Views/test/Index.cshtml", view.Item.Identifier);
                Assert.Equal("mvc.1.0.view", view.Item.Kind);
                Assert.Equal(typeof(object), view.Item.Type);
                Assert.Equal("/Views/test/Index.cshtml", view.RelativePath);
                Assert.Equal(typeof(object), view.Type);
                Assert.Equal("/Views/test/Index.cshtml", view.ViewAttribute.Path);
                Assert.Equal(typeof(object), view.ViewAttribute.ViewType);
            });
        }