Asp.net-Mvc

我可以在不是控制器的類中使用 IStringLocalizer

  • March 18, 2021

我了解如何在派生自 Controller 的類中使用 IStringLocalizer 介面,例如此處此處所述。

在不是從 Controller 派生的類中使用 IStringLocalizer 的正確方法是什麼?

我找不到任何解決這個問題的例子。

是否總是需要將 IStringLocalizer 或 IStringLocalizerFactory 傳遞給建構子?

*筆記。

我知道這是一個相當普遍的問題(堆棧溢出是針對具體的程式問題)。背景是我為 .NET 項目製作本地化工具。我試圖弄清楚我的工具必須對原始碼進行哪些更改以支持 ASP.NET Core 項目中的本地化。*

一個類是否派生自 Controller 無關緊要。

重要的是,您的對像是由依賴注入容器而不是使用 new 運算符創建的,如此所述。如果要在所有類中使用 ASP.NET Core 本地化機制,則必須採用這種模式來創建對象。

這個頁面很好地描述瞭如何創建對象,但我將嘗試舉例說明它如何與本地化一起工作。

我創建了一個 MyHelper 類。該類期望將定位器對像傳遞給建構子。它包含一個屬性 Hello,它返回一個本地化的字元串。

namespace AddingLocalization.Classes
{
 public class MyHelper
 {
   private readonly IStringLocalizer<MyHelper> _localizer;

   public MyHelper(IStringLocalizer<MyHelper> localizer)
   {
     _localizer = localizer;
   }

   public string Hello
   {
     get
     {
       return _localizer["Hello World."];
     }
   }

 }
}

在 Startup 類的 ConfigureServices 方法中,我添加了此處描述的樣板程式碼,並添加了一行將 MyHelper 類註冊到 Dependency Injection 容器。

public void ConfigureServices(IServiceCollection services)
{
 services.AddLocalization(opts => opts.ResourcesPath = "Resources");

 services.AddMvc()
         .AddViewLocalization (
              LanguageViewLocationExpanderFormat.Suffix,
              opts => opts.ResourcesPath = "Resources" )
         .AddDataAnnotationsLocalization();

 // This line registers the class MyHelper with the 
 // Dependency Injection Container.      
 services.AddTransient<MyHelper>();
}

在我的控制器類中,我在建構子中添加了一個 MyHelper 類型的參數,該參數儲存在一個成員變數中。

public class HomeController : Controller
{
 private readonly IStringLocalizer<HomeController> _localizer ;
 private readonly MyHelper                         _h ;

 public HomeController ( IStringLocalizer<HomeController> localizer,
                         MyHelper                         h )
 {
   _localizer = localizer;
   _h         = h ;
 }

 ...

 public IActionResult About()
 {
   ViewData["Message"] = _h.Hello ;
   return View();
 }

 ...
}  

因為類 MyHelper 已經註冊到依賴注入容器中,所以它會創建這個對象並自動將其傳遞給建構子。這就是依賴注入容器的神奇之處。

在 About() 方法中,我從 MyHelper 對像中獲取屬性。

程式碼就是這樣,但我想確定它實際上會從資源文件中讀取字元串。

資源文件的命名約定如下所述

它基於類的全名,沒有程序集的名稱。在我的例子中,類稱為AddingLocalization.Classes.MyHelper,程序集稱為AddingLocalization,因此相關名稱是Classes.MyHelper。

實際上有兩種命名約定,使用點或子目錄,因此我們可以將資源文件稱為其中之一

  • 類.MyHelper.resx
  • 類\MyHelper.resx

ConfigureServices 中的樣板程式碼指定了 ResourcesPath “Resources”,所以這是我們必須放置資源文件的地方。我選擇了第二個命名選項,所以我的資源文件是

  • 資源\類\MyHelper.resx

正如您在解決方案資源管理器中看到的

2017-05-28_09-30-59.png

我們不需要 Visual Studio 創建文件 MyHelper.Designer.cs 來訪問資源,因此我們應該清除資源文件的 CustomTool 屬性。

在此處輸入圖像描述

這很重要,因為如果我們不禁用自定義工具,這些名稱將不是有效的資源名稱並且可能會生成錯誤消息。

(以前的本地化方法(來自 Microsoft)一直使用虛構的資源名稱(例如,使用下劃線而不是空格)來訪問資源。新的 ASP.NET 核心本地化使用原始字元串作為資源名稱。)

最後我定義了一個資源字元串,如下所示:

在此處輸入圖像描述

我實際上還沒有嘗試過以不同的語言訪問資源(還),但是本地化程序對象確實正確讀取了資源。

引用自:https://stackoverflow.com/questions/44214387