2017-05-27 72 views
0

我知道如何在派生自Controller的類中使用IStringLocalizer接口,例如如herehere所述。我可以在不是控制器的類中使用IStringLocalizer

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

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

是否總是需要將IStringLocalizer或IStringLocalizerFactory傳遞給構造函數?

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

+0

'IStringLocalizer'通過ASP.NET Core內置的[DI容器](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection)解決。你可以在任何通過DI解析的類中的構造函數中注入'IStringLocalizer'。你可以試試嗎? –

+0

謝謝@IlyaChumakov,我會試試看。我已經找到了另一個問題,並在上​​面解釋了一下[https://stackoverflow.com/questions/37189984/dependency-injection-with-classes-other-than-a-controller-class]。事實上,我的問題接近於重複。 –

+0

是的,它看起來像這樣。 –

回答

0

如果一個類派生自Controller,則無關緊要。

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

This page對如何創建對象給出了很好的說明,但我會嘗試舉例說明它如何與本地化配合使用。

我創建了一個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."]; 
     } 
    } 

    } 
} 

在啓動類的方法ConfigureServices,我已經添加了樣板代碼描述here和添加了一行註冊類MyHelper與依賴注入容器。

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對象獲取屬性。

這就是代碼,但我想確定它會從資源文件中讀取字符串。

資源文件的命名約定描述here

它是基於類的全名,沒有程序集的名稱。在我的情況下,類名爲AddingLocalization.Classes.MyHelper,程序集名爲AddingLocalization,因此相關的名稱是Classes.MyHelper。

實際上有兩種命名約定,使用點或子目錄,所以我們可以調用的資源文件的

  • 一個Classes.MyHelper.resx
  • 類\ MyHelper.resx

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

  • 資源\類\ MyHelper.resx

,你可以在Solution Explorer中看到

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

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

enter image description here

這一點很重要,因爲該名稱不會是有效的資源名稱,將可能產生的錯誤信息,如果我們不關閉自定義工具。

(上定位方法(微軟)一直用捏造的資源名稱(例如,與underscrore而不是空間)來訪問資源。新的ASP.NET核心的本地化使用原始的字符串作爲資源名稱。)

最後,我已經定義了一個資源字符串,如下圖所示:

enter image description here

我還沒有真正嘗試用不同的語言(還)訪問資源,但定位對象沒有正確讀取資源。

相關問題