Dostęp do zasobów w plikach .resw Jak byłoby wygodniej?

0

Cześć,

piszę bota do Discorda pośredniczącego w wymianie waluty premium na standardową w grze (b. wczesna faza tworzenia tej apki), głównie dla wygody korzystania z kanału. Bota będzie można odpalić na urządzeniu z Win IoT i innych z platformy UWP i jako że z angielskim u mnie jako tako, to robię apkę z zasobami językowymi i standardowo pl i en. Bot jest mi zwyczajnie potrzebny, a i później wrzucę gdzieś w sklep, co by sobie każdy mógł go gdzieś tam we własnym zakresie odpalić. Nie wiem jednak jak wygodnie zarządzać w UWP zasobami językowymi z plików .resw.

Wymyśliłem sobie taką klasę z poniższym interfejsem:

using System;
using System.Collections.Generic;

namespace Discord_Bot
{
    public enum DiscordBot
    {
        CancelErrorInfo,
        DenyOffer,
        DenyOrder,
        FullOffer,
        FullOrder,
        NoResults,
        NoRightRole,
        Offer,
        OfferAlreadyPlaced,
        OfferConfirmed,
        OfferFinalized,
        Order,
        OrderAlreadyPlaced,
        OrderConfirmed,
        OrderFeedback,
        OrderFinalized,
        SellersNotification
    }

    public enum Messages
    {
        LogOutWarning,
        No,
        Warning,
        Yes
    }

    public enum Resources
    {
        About,
        Home
    }

    public interface ILanguageResources
    {
        string GetString<T>(T resource, List<string> objectsForInterpolation = null, string key = null) where T : Enum;
        string StringInterpolation(string input, List<string> stringsForInterpolation, string key);
    }
}

Interfejs sobie wstrzykuję przez DI i korzystam w całym programie, ale zastanawia mnie czy to jest dobre rozwiązanie, czy nie lepiej wymyślić coś innego.

Niby to tylko bot, ale ciągle się uczę i każdy, nawet mały projekt chciałbym mieć przygotowany do rozwoju. Fajnie byłoby gdyby ktoś podpowiedział, czy jest jakieś lepsze i wygodniejsze rozwiązanie na zarządzanie takimi zasobami. Może pominąłem jakieś narzędzie w UWP, może coś innego. W tym wypadku każda wartość dodana do pliku .resw wymaga dopisania do enum nowych kluczy lub całego enum jeśli mówimy o nowym pliku. Ważna jest dla mnie interpolacja, bo wartości w .resw posiadają znaczniki podmieniane w kolejności za zmienne podane jako listę stringów i to pozwala mi jak na razie ograniczyć ilość zasobów w plikach .resw.

1

Wygodniejsze? nie wiem, ja używam czegoś takiego

public static class Messages
{
	private static Dictionary<string, string> _messages = new Dictionary<string, string>();

	public static string GetMessage(string id, params dynamic[] args)
	{
		if (!_messages.TryGetValue(id, out var message))
			return $"Something went wrong. {id}";

		try
		{
			return string.Format(message, args);
		}
		catch(FormatException)
		{
			return $"Something went wrong. {id}";
		}
	}

	public static void Populate(Dictionary<string, string> seed)
	{
		if (_messages.Count > 0)
		{
			// exception?
			return;
		}

		_messages = seed; // deep copy?
	}
}

Ładuje jakiś polish / english.jsonxmltxtrarzipjpg i wypełniam

Messages.Populate(new Dictionary<string, string>
{
	{ "ERR_USER_NAME_TOO_SHORT", "Username '{0}' is too short. It should be at least {1} characters long."},
	{ "ERR_USER_INVALID_CREDS", "Incorrect credentials. Please contact support in order to recover your account."}
});

Console.WriteLine(Messages.GetMessage("ERR_USER_NAME_TOO_SHORT", "param1", 87));
Console.WriteLine(Messages.GetMessage("ERR_USER_INVALID_CREDS"));

Username 'param1' is too short. It should be at least 87 characters long.
Incorrect credentials. Please contact support in order to recover your account.

0

Jak zwykle deczko przekombinowałem. Pozbyłem się własnej interpolacji skoro jest przecież string.Format. Użyłem przekazania parametrów ze zmiennych przez params object[] args. Jeśli chodzi o klucze, to wolę nie używać ich w postaci stringów. Tak czy siak dziękuję za wskazówkę! Kodu ubywa.

    public enum DiscordBot
    {
        CancelErrorInfo,
        DenyOffer,
        DenyOrder,
        FullOffer,
        FullOrder,
        NoResults,
        NoRightRole,
        Offer,
        OfferAlreadyPlaced,
        OfferConfirmed,
        OfferFinalized,
        Order,
        OrderAlreadyPlaced,
        OrderConfirmed,
        OrderFeedback,
        OrderFinalized,
        SellersNotification
    }

    public enum Messages
    {
        LogOutWarning,
        No,
        Warning,
        Yes
    }

    public enum Resources
    {
        About,
        Home
    }

    public interface ILanguageResources
    {
        
        string GetString<T>(T resource, params object[] args) where T : Enum;
    }
        public string GetString<T>(T resource, params object[] args) where T : Enum
        {
 
            return ExtractResources(typeof(T).Name, resource.ToString(), args);
        }

        private string ExtractResources(string name, string resource, params object[] args)
        {
            var resourceLoader = ResourceLoader.GetForViewIndependentUse(name);
            var content = resourceLoader.GetString(resource);

            if (args.Count() > 0)
                return string.Format(content, args);
            else return content;
        }

1 użytkowników online, w tym zalogowanych: 0, gości: 1