Skip to content

Commit e69d378

Browse files
RazorClassLibrary Components (#12134)
RazorLibrary components
1 parent 5a0a7aa commit e69d378

File tree

15 files changed

+124
-20
lines changed

15 files changed

+124
-20
lines changed

src/ProjectTemplates/Web.ProjectTemplates/Microsoft.DotNet.Web.ProjectTemplates.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
MicrosoftEntityFrameworkCoreToolsPackageVersion=$(MicrosoftEntityFrameworkCoreToolsPackageVersion);
1818
MicrosoftExtensionsHostingPackageVersion=$(MicrosoftExtensionsHostingPackageVersion);
1919
MicrosoftNETCoreAppRuntimeVersion=$(MicrosoftNETCoreAppRuntimeVersion);
20+
TemplateComponentsPackageVersion=$(TemplateComponentsPackageVersion);
2021
</GeneratedContentProperties>
2122
</PropertyGroup>
2223

@@ -25,6 +26,7 @@
2526
<PackageVersionVariableReference Include="$(RepoRoot)src\Azure\AzureAD\Authentication.AzureAD.UI\src\Microsoft.AspNetCore.Authentication.AzureAD.UI.csproj" />
2627
<PackageVersionVariableReference Include="$(RepoRoot)src\Azure\AzureAD\Authentication.AzureADB2C.UI\src\Microsoft.AspNetCore.Authentication.AzureADB2C.UI.csproj" />
2728
<PackageVersionVariableReference Include="$(RepoRoot)src\Components\Components\src\Microsoft.AspNetCore.Components.csproj" />
29+
<PackageVersionVariableReference Include="$(RepoRoot)src\Components\Web\src\Microsoft.AspNetCore.Components.Web.csproj" />
2830
<PackageVersionVariableReference Include="$(RepoRoot)src\Identity\EntityFrameworkCore\src\Microsoft.AspNetCore.Identity.EntityFrameworkCore.csproj" />
2931
<PackageVersionVariableReference Include="$(RepoRoot)src\Identity\UI\src\Microsoft.AspNetCore.Identity.UI.csproj" />
3032
<PackageVersionVariableReference Include="$(RepoRoot)src\Middleware\Diagnostics.EntityFrameworkCore\src\Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.csproj" />

src/ProjectTemplates/Web.ProjectTemplates/RazorClassLibrary-CSharp.csproj.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111
<ItemGroup Condition="'$(SupportPagesAndViews)' == 'True'">
1212
<FrameworkReference Include="Microsoft.AspNetCore.App" />
1313
</ItemGroup>
14+
1415
<ItemGroup Condition="'$(SupportPagesAndViews)' != 'True'">
1516
<PackageReference Include="Microsoft.AspNetCore.Components" Version="${MicrosoftAspNetCoreComponentsPackageVersion}" />
17+
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="${MicrosoftAspNetCoreComponentsWebPackageVersion}" />
1618
</ItemGroup>
1719

1820
</Project>

src/ProjectTemplates/Web.ProjectTemplates/content/RazorClassLibrary-CSharp/.template.config/template.json

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,22 @@
2222
"preferNameDirectory": true,
2323
"sources": [
2424
{
25-
"modifiers": [{
26-
"condition": "(!SupportPagesAndViews)",
27-
"exclude": [
28-
"Areas/**"
29-
]
30-
}]
25+
"modifiers": [
26+
{
27+
"condition": "(!SupportPagesAndViews)",
28+
"exclude": [
29+
"Areas/**"
30+
]
31+
},
32+
{
33+
"condition": "(SupportPagesAndViews)",
34+
"exclude": [
35+
"Component1.razor",
36+
"ExampleJsInterop.cs",
37+
"wwwroot/**"
38+
]
39+
}
40+
]
3141
}
3242
],
3343
"symbols": {
@@ -56,7 +66,7 @@
5666
"SupportPagesAndViews": {
5767
"type": "parameter",
5868
"datatype": "bool",
59-
"defaultValue": "true",
69+
"defaultValue": "false",
6070
"description": "Whether to support adding traditional Razor pages and Views in addition to components to this library."
6171
}
6272
},

src/ProjectTemplates/Web.ProjectTemplates/content/RazorClassLibrary-CSharp/.template.config/vs-2017.3.host.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,14 @@
1212
},
1313
"order": 700,
1414
"icon": "vs-2017.3/RazorClassLibrary.ico",
15-
"learnMoreLink": "https://go.microsoft.com/fwlink/?linkid=872103"
15+
"learnMoreLink": "https://go.microsoft.com/fwlink/?linkid=872103",
16+
"symbolInfo": [
17+
{
18+
"id": "SupportPagesAndViews",
19+
"name": {
20+
"text": "_Support pages and views"
21+
},
22+
"isVisible": "true"
23+
}
24+
]
1625
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<div class="my-component">
2+
This Blazor component is defined in the <strong>RazorClassLibrary-CSharp</strong> package.
3+
</div>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using Microsoft.JSInterop;
2+
using System.Threading.Tasks;
3+
4+
namespace RazorClassLibrary_CSharp
5+
{
6+
public class ExampleJsInterop
7+
{
8+
public static Task<string> Prompt(IJSRuntime jsRuntime, string message)
9+
{
10+
// Implemented in exampleJsInterop.js
11+
return jsRuntime.InvokeAsync<string>(
12+
"exampleJsFunctions.showPrompt",
13+
message);
14+
}
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// This file is to show how a library package may provide JavaScript interop features
2+
// wrapped in a .NET API
3+
4+
window.exampleJsFunctions = {
5+
showPrompt: function (message) {
6+
return prompt(message, 'Type anything here');
7+
}
8+
};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/*
2+
This file is to show how CSS and other static resources (such as images) can be
3+
used from a library project/package.
4+
*/
5+
6+
.my-component {
7+
border: 2px dashed red;
8+
padding: 1em;
9+
margin: 1em 0;
10+
background-image: url('background.png');
11+
}

src/ProjectTemplates/test/BaselineTest.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ private string SanitizeArgs(string arguments)
111111
text += LanguageRegex.Match(arguments)
112112
.Groups.TryGetValue("language", out var language) ? language.Value.Replace("#", "Sharp") : "";
113113

114+
if (arguments.Contains("--support-pages-and-views true"))
115+
{
116+
text += "supportpagesandviewstrue";
117+
}
118+
114119
return text;
115120
}
116121

src/ProjectTemplates/test/Helpers/Project.cs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,44 +41,52 @@ public class Project
4141
public ITestOutputHelper Output { get; set; }
4242
public IMessageSink DiagnosticsMessageSink { get; set; }
4343

44-
internal async Task<ProcessEx> RunDotNetNewAsync(string templateName, string auth = null, string language = null, bool useLocalDB = false, bool noHttps = false)
44+
internal async Task<ProcessEx> RunDotNetNewAsync(string templateName, string auth = null, string language = null, bool useLocalDB = false, bool noHttps = false, string[] args = null)
4545
{
4646
var hiveArg = $"--debug:custom-hive \"{TemplatePackageInstaller.CustomHivePath}\"";
47-
var args = $"new {templateName} {hiveArg}";
47+
var argString = $"new {templateName} {hiveArg}";
4848

4949
if (!string.IsNullOrEmpty(auth))
5050
{
51-
args += $" --auth {auth}";
51+
argString += $" --auth {auth}";
5252
}
5353

5454
if (!string.IsNullOrEmpty(language))
5555
{
56-
args += $" -lang {language}";
56+
argString += $" -lang {language}";
5757
}
5858

5959
if (useLocalDB)
6060
{
61-
args += $" --use-local-db";
61+
argString += $" --use-local-db";
6262
}
6363

6464
if (noHttps)
6565
{
66-
args += $" --no-https";
66+
argString += $" --no-https";
67+
}
68+
69+
if (args != null)
70+
{
71+
foreach (var arg in args)
72+
{
73+
argString += " " + arg;
74+
}
6775
}
6876

6977
// Save a copy of the arguments used for better diagnostic error messages later.
7078
// We omit the hive argument and the template output dir as they are not relevant and add noise.
71-
ProjectArguments = args.Replace(hiveArg, "");
79+
ProjectArguments = argString.Replace(hiveArg, "");
7280

73-
args += $" -o {TemplateOutputDir}";
81+
argString += $" -o {TemplateOutputDir}";
7482

7583
// Only run one instance of 'dotnet new' at once, as a workaround for
7684
// https://github.com/aspnet/templating/issues/63
7785

7886
await DotNetNewLock.WaitAsync();
7987
try
8088
{
81-
var execution = ProcessEx.Run(Output, AppContext.BaseDirectory, DotNetMuxer.MuxerPathOrDefault(), args);
89+
var execution = ProcessEx.Run(Output, AppContext.BaseDirectory, DotNetMuxer.MuxerPathOrDefault(), argString);
8290
await execution.Exited;
8391
return execution;
8492
}

src/ProjectTemplates/test/Helpers/ProjectFactoryFixture.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public async Task<Project> GetOrCreateProject(string projectKey, ITestOutputHelp
4848
NodeLock = NodeLock,
4949
Output = outputHelper,
5050
DiagnosticsMessageSink = DiagnosticsMessageSink,
51-
ProjectGuid = Guid.NewGuid().ToString("N").Substring(0, 6)
51+
ProjectGuid = Path.GetRandomFileName().Replace(".", string.Empty)
5252
};
5353
project.ProjectName = $"AspNet.{key}.{project.ProjectGuid}";
5454

src/ProjectTemplates/test/RazorClassLibraryTemplateTest.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,25 @@ public RazorClassLibraryTemplateTest(ProjectFactoryFixture projectFactory, ITest
2121
public ProjectFactoryFixture ProjectFactory { get; }
2222
public ITestOutputHelper Output { get; }
2323

24+
[Fact]
25+
public async Task RazorClassLibraryTemplate_WithViews_Async()
26+
{
27+
Project = await ProjectFactory.GetOrCreateProject("razorclasslibwithviews", Output);
28+
29+
var createResult = await Project.RunDotNetNewAsync("razorclasslib", args: new[] { "--support-pages-and-views", "true" });
30+
Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult));
31+
32+
var publishResult = await Project.RunDotNetPublishAsync();
33+
Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult));
34+
35+
// Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release
36+
// The output from publish will go into bin/Release/netcoreapp3.0/publish and won't be affected by calling build
37+
// later, while the opposite is not true.
38+
39+
var buildResult = await Project.RunDotNetBuildAsync();
40+
Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult));
41+
}
42+
2443
[Fact]
2544
public async Task RazorClassLibraryTemplateAsync()
2645
{

src/ProjectTemplates/test/SpaTemplateTest/SpaTemplateTestBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ private void TestBasicNavigation(bool visitFetchData, bool usesAuth, IWebDriver
203203
{
204204
browser.Exists(By.TagName("ul"));
205205
// <title> element gets project ID injected into it during template execution
206-
browser.Contains(Project.ProjectGuid, () => browser.Title);
206+
browser.Contains(Project.ProjectGuid.Replace(".", "._"), () => browser.Title);
207207

208208
// Initially displays the home page
209209
browser.Equal("Hello, world!", () => browser.FindElement(By.TagName("h1")).Text);

src/ProjectTemplates/test/template-baselines.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -871,9 +871,20 @@
871871
}
872872
},
873873
"razorclasslib": {
874-
"None": {
874+
"ComponentsOnly": {
875875
"Template": "razorclasslib",
876876
"Arguments": "new razorclasslib",
877+
"Files": [
878+
"wwwroot/background.png",
879+
"wwwroot/exampleJsInterop.js",
880+
"wwwroot/styles.css",
881+
"Component1.razor",
882+
"ExampleJsInterop.cs"
883+
]
884+
},
885+
"ViewsOnly": {
886+
"Template": "razorclasslib",
887+
"Arguments": "new razorclasslib --support-pages-and-views true",
877888
"Files": [
878889
"Areas/MyFeature/Pages/Page1.cshtml",
879890
"Areas/MyFeature/Pages/Page1.cshtml.cs"

0 commit comments

Comments
 (0)