Избегайте dll-зависимостей в классе - PullRequest
0 голосов
/ 30 марта 2012

У нас есть класс, который переводит пользовательский интерфейс на несколько языков. Основная идея этого класса заключается в том, что он просто проверяет все элементы управления в форме и считывает текстовые значения для каждого элемента управления из XML-файла.

foreach(Control control in form.Controls)
{
    if (control is Label)
        ReadTextForLabel(control);
    else if (control is MySuperCoolLabel)
        ReadTextForMySuperCoolLabel(control);
    ...
}

Поэтому мы попытались создать универсальный класс для перевода каждого элемента управления в наших программах.

Некоторое время назад мы столкнулись с проблемой, что у нас слишком много классов, таких как MySuperCoolLabel из разных библиотек. Если мы хотим перевести интерфейс в новую программу, используя наш класс перевода, мы должны добавить все эти dll с помощью SuperCoolLabels, даже если в программе нет никаких SuperCoolLabels.

Вопрос: как избежать всех этих зависимостей и при этом иметь один универсальный класс для перевода программ?

Ответы [ 4 ]

2 голосов
/ 30 марта 2012

Может быть, вы можете попытаться различить элементы управления не по типу, а по типу имен в виде строк. что-то вроде;

if (control.GetType().ToString() == "Label")
    ReadTextForLabel(control);
else if (control.GetType().ToString() == "MySuperCoolLabel")
    ReadTextForMySuperCoolLabel(control);

С другой стороны, мне интересно, почему вы не использовали встроенную поддержку .Net для нескольких языков.

1 голос
/ 30 марта 2012

Ну, зависимости являются метрикой архитектуры программы.Для ясности:

I предположим, вы пишете ReadTextForMySuperCoolLabel(..), потому что вам нужно перевести некоторые конкретные свойства , которые , которые вы, возможно, не встретите в другие элементы управленияты используешь.

Если это правда, нет способа избежать зависимости, о которой вы говорите.Используйте ваше прямое назначение, используйте рефлексию, используйте что-нибудь еще ... где-то должен быть кто-то, кто скажет: «Это MySuperControl, так что это , это другое, так что , что ".

Если есть способ обобщить присвоение свойства.Например, все элементы управления в вашем приложении могут иметь свойство Text.В этом случае может сделать материал общим.

Удачи.

0 голосов
/ 30 марта 2012

Ваша проблема на самом деле является нарушением принципа подстановки Лискова, поскольку ваш класс перевода должен обрабатывать каждый производный тип отдельно.

Мы знаем, что winforms имеют типы элементов управления: контейнеры и элементы управления.Контейнер содержит несколько элементов управления, в то время как элемент управления является просто элементом управления;)

Мы можем использовать этот knowlegde для создания универсального переводчика форм:

public class UniversalFormTranslater
{
    public void TranslateForm(System.Windows.Forms.ContainerControl container)
    {
        var name = container.Name;
        var originalText = container.Text;
        if (!string.IsNullOrEmpty(originalText))
            container.Text = Translate(name);

        TranslateControl(name, container);
    }

    private void TranslateControl(string parentName, System.Windows.Forms.ContainerControl control)
    {
        var name = parentName + "." + control.Name;
        var originalText = control.Text;
        if (!string.IsNullOrEmpty(originalText))
            control.Text = Translate(name);
    }

    private void TranslateControl(string parentName, System.Windows.Forms.ContainerControl container)
    {
        var name = parentName + "." + container.Name;
        var originalText = container.Text;
        if (!string.IsNullOrEmpty(originalText))
            container.Text = Translate(name);

        foreach (var control in container.Controls)
        {
            TranslateControl(name, control);
        }
    }

    public void Translate(string controlName)
    {
        // return the translation.
    }
}

Он выглядит для таких строк:

  • Form1.MyGroupPanel.Label1
  • Form1.MyTextBox

Перевести с помощью:

var translator = new UniversalFormTranslater();
translator.TranslateForm(form1);
0 голосов
/ 30 марта 2012

Что ж, одним из способов было бы позднее связать все ваши классы, используя фреймворк для инъекций зависимостей (например, Castle Windsor) или развернув свой собственный, создав такие классы следующим образом:

var myCoolClass = Activator.CreateInstance(  typeof( MySuperCoolTextBox ) )

Таким образом, вам не нужно добавлять ссылку на библиотеку SuperCool, а только включать ее в свои бинарные файлы. Тем не менее, я предполагаю, что элементы управления SuperCool используются в конструкторе форм, поэтому вы не сможете установить такие элементы управления следующим образом.

...