sobota, 14 sierpnia 2010

Zasoby(Resources) - czyli wielojezyczne strony

Dziś krotki wpis na temat wielojęzycznych stron. Będę opierał się na plikach .resx. Mechanizm jest wbudowany w sama platformę net ale opisze co i jak rozwiązałem w praktyce.

ResourceHelper
Jest to nasz obiekt pomocniczy ułatwiający pobieranie wartości z plików .resx. Jest rownież odpowiedzialny za inicjalizacje ResourceManagera czyli głównego obiektu od strony platformy .NET który pozwala zarządzać zasobami. Sama klasa nie jest skomplikowana. Oprócz metody inicjalizujacej posiada tylko jedna metodę która pobiera wartość typu string z naszych plików z zasobami. Klasa wygląda ona tak:
public static class ResourceHelper
{
    private static ResourceManager _resourceManager;

    public static void Initialize(ResourceManager resourceManager)
    {
        Check.Argument.IsNotNull(resourceManager, "resourceManager");

        _resourceManager = resourceManager;
    }

    public static string GetErrorMessage(string key)
    {
        string errorMessage = _resourceManager.GetString(key);

        if (errorMessage == null)
            throw new ArgumentException(_resourceManager.GetString(ResourceKey.Common.InvalidMessage));

        return errorMessage;
    }
Sama klasa jest statyczna. Jak można zauważyć występuje tutaj również klasa o nazwie ResourceKey. Ta klasa posiada wszystkie informacje na temat nazw danych zmiennych w plikach .resx. Po prostu nie musimy zawsze wpisywać danego stringa tylko używamy klasy pomocniczej i w wypadku jakiś zmian tylko w jednym miejscu będzie to potrzebne. Takie małe ułatwienie :) W nowo dodanym projekcje oprócz plików .resx jest tez fabryka która generuje nam odpowiedniego resourceManagera którym to później inicjujemy naszego helpera. Wygląda ona bardzo prosto:
public class ResourceManagerFactory : IResourceManagerFactory
{
    private ResourceManager _resourceManager;

    public ResourceManagerFactory()
    {

    }

    public ResourceManager CreateResourceManager()
    {
        if (_resourceManager == null)
            _resourceManager = new ResourceManager("mForum.Resources.ErrorsAndExceptions.ErrorMessages", Assembly.GetExecutingAssembly());

        return _resourceManager;
    }
}
Sam konstruktor ResourceManagera przyjmuje 2 argumenty. 1 to nazwa danej klasy która została wygenerowana wraz z utworzeniem pliku .resx. Drugi to dana biblioteka w której się znajduje ten plik.

Natomiast w widokach przyjąłem troszeczkę inne podejście jeżeli chodzi o zasoby. Zasoby standartowo sa internal czyli dostępne tylko z poziomu danej biblioteki natomiast u mnie wszystkie zasoby zwiazane z warstwa prezentacji będą publiczne co powoduje ze możemy się bezpośrednio odwoływać do pliku .resx z naszych widoków.

Oprócz tych zmian oczywiście dodałem testy związane z naszym ResourceHelperem.

2 komentarze:

Agares pisze...

1. Dlaczego funkcję nazwałeś GetErrorMessage? Tylko błędy będziesz tłumaczyć? :)

2. Po co czarujesz z metodą Initialize? C# obsługuje statyczne konstruktory.

Krzysztof Hrabia pisze...

Sorki ze tak późno odpisuje ale ostatnio nie miałem w ogóle czasu żeby poświecić na projekt.

1. W warstwie Modelu tylko błędy będą potrzebne. W tym celi specjalny interfejs który pomaga usystematyzować jakie błędy mogą wystąpić w aplikacji. Natomiast do danych z warstwy prezentacji(widoku) będę się odnosił bezpośrednio do resource.

2. Nie lubię korzystać z statycznych konstruktorów. W taki sposób wszystko jest jasne i klarowne.

Prześlij komentarz