2017-06-01 6 views
4

Ich mache eine ASP.NET Core 1.1 App und versuche, Lokalisierung einzurichten.ASP.NET Core 1.1 Localization Generischer Dienst

Wenn ich auf meiner ValuesController die Implementierung von IStringLocalizer mache, funktioniert es gut und lokalisieren meine Ressource-Datei.

public ValuesController(IStringLocalizer<ValuesController> localizer, IService<BaseEntity> service) 
{ 
    _localizer = localizer; 
    _service = service; 
} 

Der Code über meine Ressourcen auf "Resources/Controller/ValuesController.en-US.resx" finden.

Aber wenn ich versuche, die IStringLocalizer mit einem generischen Dienst zu injizieren, kann es meine Ressourcendatei nicht finden.

public class Service<T> : IService<T> 
    where T : BaseEntity 
{ 
    #region Properties 
    protected IRepository Repository { get; set; } 
    protected IUnitOfWorkFactory UnitOfWorkFactory { get; set; } 
    private readonly ILogger _logger; 
    private readonly IStringLocalizer _localizer; 

    #endregion 

    #region Ctor 
    public Service(IRepository repository, IUnitOfWorkFactory unitOfWorkFactory, 
     ILogger<Service<T>> logger, IStringLocalizer<Service<T>> localizer) 
    { 
     Repository = repository; 
     UnitOfWorkFactory = unitOfWorkFactory; 
     _logger = logger; 
     _localizer = localizer; 
    } 
} 

Der obige Code finden nicht meine Ressource auf "Ressourcen/Dienstleistungen/Basis/Service.en-US.resx"

Irgendeine Idee, wie man es tun?

--- EDIT

MyControl.Api (Startup.cs)

Namensraum MyControl.Api

services.AddLocalization(options => options.ResourcesPath = "Resources"); 

Diese Linie ist inside "MyControl.Api", wobei in dem Namensraum ist, "MyControl.Api".

die Ordner Ressourcen in dieser aplication Arbeit für "Resources/Controllers"

Meine Leistungen im Namensraum "MyControl.Services" sind

die Ordner Ressourcen in diesem Projekt (zwei Projekte innerhalb derselben Lösung) sind

"Resources/Dienstleistungen/Base"

der Namespace meiner Service-Datei ist "MyControl.Services.Services.Base"

+0

standardmäßig sollte es funktionieren, wenn Pfad zu der Ressource-Datei korrekt ist. Fügen Sie den Namespace des Dienstes und Ihren Aufruf 'services.AddLocalization' hinzu. –

+0

Hinzugefügt. Service.cs-Namespace> "MyControl.Services.Services.Base" Ressourcen-Ordner bei "MyControl.Services" Projekt> "Ressourcen/Dienste/Basis" –

Antwort

3

Erläuterung

Sie haben Recht, das Problem liegt in der generischen Klasse. Entsprechend der source code von ResourceManagerStringLocalizer (es ist Standard IStringLocalizer Implementierung) - diese Klasse enthält _resourceBaseName private Feld. Die gleiche Zeichenfolge auch is used zu Ressourcen-Dateien als Suchpfad-Parameter in ResourceManager Klasse suchen.

Wenn IStringLocalizer in eine geschlossene generischen Typ-Instanz eingespritzt wird, wird dieses Feld wie falsch mit etwas gesetzt:

FooProject.Resources.Services.FooService`1 [[System.Double, System.Private.CoreLib ...

Statt richtige:

FooProject.Resources.Services.FooService

Sie können den Localizer-Wert _resourceBaseName im Debugger überprüfen.Es ist wahrscheinlich ein Fehler und Sie würden ein Problem darüber auf GitHub öffnen: https://github.com/aspnet/Localization/issues.

Umgehung

Es ist möglich, eine ResourceManagerStringLocalizer Instanz manuell zu erstellen. Wir sollten nehmen diese baseName Teil aus einer Klasse voller Name ohne csproj-Dateinamen und ohne einen Klassennamen selbst:

Vollklassenname:

MyCsprojFileName.AnyFolder.SubFolder.FooClass

baseName:

AnyFolder.SubFolder

Für den von Ihnen angegebenen Code ist baseName wahrscheinlich "Services.Base". Lassen Sie uns einige Code schreiben, um es in allgemeiner Weise zu erhalten:

public class FooService<T> 
{ 
    private readonly IStringLocalizerFactory _factory; 

    public FooService(IStringLocalizerFactory factory) 
    { 
     _factory = factory; 
    } 

    public IStringLocalizer GetLocalizer() 
    { 
     var type = typeof(FooService<>); 

     string assemblyName = type.GetTypeInfo().Assembly.GetName().Name; 
     string typeName = type.Name.Remove(type.Name.IndexOf('`')); 
     string baseName = (type.Namespace + "." + typeName).Substring(assemblyName.Length).Trim('.'); 

     var localizer = _factory.Create(baseName, assemblyName); 

     return localizer; 
    } 
} 
+0

Um eine "Must-Have" -Ressourcen für jede Klasse zu vermeiden und folglich dupliziert Nachrichten Ich habe eine Inhaberklasse "LanguageLocalizer.cs" erstellt und nur alle meine Localizer davon initalisieren. Aber deine Antwort ist richtig. Vielen Dank ! –

Verwandte Themen