我習慣將常用功能包成套件讓各專案共享。以昨天介紹的 QR Code Tag Helper 為例,通常會跟一堆網頁功能放進某個開發工具箱專案,編譯成 NuGet Package 方便各專案引用,而 ASP.NET Core 讓我們能輕易實現這個理想,只要像下圖這樣:

建立一個類別程式庫專案 SharedController,將 PageQRTagHelper.cs 搬過去,隨便多寫個 ComputerInfoController 方便測試:

using Microsoft.AspNetCore.Mvc;

namespace SharedController
{
    public class ComputerInfoController : Controller
    {
        public IActionResult Index()
        {
            return Content($"ComputerName={Environment.GetEnvironmentVariable("COMPUTERNAME")}");
        }
    }
}

當 DemoWeb 參照 SharedController 專案,ASP.NET Core 自動掃瞄參照組件所包含的 Controller、TagHelper、View Component、Razor Page... 等等,在 DemoWeb 可直接引用。

在 DemoWeb/Views/Index.cshtml @addTagHelper *,SharedController 納入來自 SharedControllerd.dll 的 TagHelper 即可引用 <page-qr-code>,另外嵌個 IFrame 指向 /ComputerInfo 看看 SharedController 的 ComputerInfoController 是否能運作:

@addTagHelper *,SharedController
@{
    ViewData["Title"] = "Home Page";
}

<div class="text-center">
    <div>黑暗執行緒</div>
    <div><page-qr-code size="3" url="https://blog.darkthread.net"></page-qr-code></div>
    <iframe src="/ComputerInfo" style="width: 180px; border: 1px solid gray;"></iframe>
</div>

輕鬆秒殺。

最後補充兩則進階技巧。延伸閱讀:Share controllers, views, Razor Pages and more with Application Parts

  1. 檢查 ASP.NET Core 目前載入的 Controller 跟 TagHelper

     public IActionResult Check()
     {
         var sb = new StringBuilder();
    
         var controllerFeature = new ControllerFeature();
         partManager.PopulateFeature(controllerFeature);
         sb.AppendLine("Controllers:");
         foreach (var c in controllerFeature.Controllers)
             sb.AppendLine($" * {c.FullName} @ {c.Assembly.Location}");
    
         var tagHelperFeature = new TagHelperFeature();
         partManager.PopulateFeature(tagHelperFeature);
         sb.AppendLine("TagHelpers:");
         foreach (var t in tagHelperFeature.TagHelpers)
             sb.AppendLine($" * {t.FullName} @ {t.Assembly.Location}");
    
         return Content(sb.ToString());
     }
    

    執行結果:

  2. 不要載入某些組件中的 Controller

    builder.Services.AddControllersWithViews()
     .ConfigureApplicationPartManager(apm =>
     {
         var toRemove = apm.ApplicationParts.Where(p => p.Name == "SharedController").SingleOrDefault();
         if (toRemove != null)
             apm.ApplicationParts.Remove(toRemove);
     });
    

Tips of how to use class library to share controller and tag helpers with ASP.NET Core applications.


Comments

Be the first to post a comment

Post a comment