日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Hello Blazor:(9)Source Generators生成导航菜单

發布時間:2023/12/4 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Hello Blazor:(9)Source Generators生成导航菜单 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

最近寫了多篇關于Source Generators的文章,發現它確實可以簡化我們的部分開發工作。

這不,我又盯上了Blazor。

問題

默認的NavMenu.razor組件用于顯示導航菜單,它的部分代碼如下:

<div?class="@NavMenuCssClass"?@onclick="ToggleNavMenu"><ul?class="nav?flex-column"><li?class="nav-item?px-3"><NavLink?class="nav-link"?href=""?Match="NavLinkMatch.All"><span class="oi?oi-home"?aria-hidden="true"></span>?Home</NavLink></li><li?class="nav-item?px-3"><NavLink?class="nav-link"?href="counter"><span class="oi?oi-plus"?aria-hidden="true"></span>?Counter</NavLink></li><li?class="nav-item?px-3"><NavLink?class="nav-link"?href="fetchdata"><span class="oi?oi-list-rich"?aria-hidden="true"></span>?Fetch?data</NavLink></li></ul> </div>

這也就意味著,如果我們增加一個頁面,就要修改一次NavMenu.razor組件,這當然是不合適的。

實現原理

我們查看obj\Debug\net5.0\Razor\Pages\Counter.razor.g.cs(編譯時生成的中間文件),可以看到如下代碼:

[Microsoft.AspNetCore.Components.RouteAttribute("/counter")] public?partial?class?Counter?:?Microsoft.AspNetCore.Components.ComponentBase

它其實對應源代碼里的:

@page?"/counter"

也就是說,只要我們遍歷所有的Microsoft.AspNetCore.Components.RouteAttribute,獲得路由信息放到List<Menu>即可。

具體實現代碼如下:

[Generator]public?class?MenuGenerator?:?ISourceGenerator{private?const?string?MenuClassText?=?@" public?class?Menu {public?string?Route?{?get;?set;?}public?string?Title?{?get;?set;?} }";public?void?Initialize(GeneratorInitializationContext?context){}public?void?Execute(GeneratorExecutionContext?context){context.AddSource("Menu",?SourceText.From(MenuClassText,?Encoding.UTF8));var?options?=?(context.Compilation?as?CSharpCompilation).SyntaxTrees[0].Options?as?CSharpParseOptions;var?compilation?=?context.Compilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(SourceText.From(MenuClassText,?Encoding.UTF8),?options));var?allClasses?=?compilation.SyntaxTrees.SelectMany(x?=>?x.GetRoot().DescendantNodes().OfType<ClassDeclarationSyntax>());var?sourceBuilder?=?new?StringBuilder(@" using?System.Collections.Generic; namespace?MenuGenerator {public?static?class?NavHelper{public?static?IEnumerable<Menu>?GetMenus(){return?new?List<Menu>?{");foreach?(var?classDeclarationSyntax?in?allClasses){var?routeAttribute?=?classDeclarationSyntax.AttributeLists.SelectMany(x?=>?x.Attributes).FirstOrDefault(attr?=>?attr.Name.ToString()?==?"Microsoft.AspNetCore.Components.RouteAttribute");if?(routeAttribute?!=?null){var?routeArg?=?routeAttribute.ArgumentList.Arguments.First();var?routeExpr?=?routeArg.Expression;var?semanticModel?=?compilation.GetSemanticModel(classDeclarationSyntax.SyntaxTree);var?route?=?semanticModel.GetConstantValue(routeExpr).ToString();if?(route?==?@"/")?continue;var?title?=?classDeclarationSyntax.Identifier.ToString();sourceBuilder.Append($@"? new?Menu{{?Route?=?""{route}"",?Title?=?""{title}""?}},");}}sourceBuilder.Append(@" }; }} }");context.AddSource("Mapper",?SourceText.From(sourceBuilder.ToString(),?Encoding.UTF8));}}

使用示例

修改NavMenu.razor代碼如下:

<div?class="@NavMenuCssClass"?@onclick="ToggleNavMenu"><ul?class="nav?flex-column"><li?class="nav-item?px-3"><NavLink?class="nav-link"?href=""?Match="NavLinkMatch.All"><span class="oi?oi-home"?aria-hidden="true"></span>?Home</NavLink></li>@foreach?(var?menu?in?MenuGenerator.NavHelper.GetMenus()){<li?class="nav-item?px-3"><NavLink?class="nav-link"?href="@menu.Route"><span class="oi?"?aria-hidden="true"></span>?@menu.Title</NavLink></li>}</ul> </div>

編譯后可以看到自動生成的代碼:

運行后測試,工作正常,成功!

結論

菜單信息還有許多地方需要擴展,比如順序、圖標、菜單名稱等,這些可以通過添加自定義Attribute實現。

如果你覺得這篇文章對你有所啟發,請關注我的個人公眾號”My IO“,記住我!

總結

以上是生活随笔為你收集整理的Hello Blazor:(9)Source Generators生成导航菜单的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。