避免在类中使用dll依赖项

时间:2012-03-30 09:50:50

标签: c# .net design-patterns architecture

我们有一个将用户界面翻译成多种语言的类。这个类的基本思想是它只是检查表单上的所有控件,并从xml文件中读取每个控件的文本值。

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

因此,我们尝试创建一个通用类来翻译程序中的每个控件。

前一段时间我们遇到了一个问题,即我们有太多的类,比如来自不同库的MySuperCoolLabel。如果我们想要使用我们的翻译类在新程序中翻译界面,我们必须使用我们的SuperCoolLabels添加所有这些dll,即使程序中没有任何SuperCoolLabels。

问题是:如何避免所有这些依赖关系并仍然有一个通用类来翻译程序?

4 个答案:

答案 0 :(得分:2)

也许您可以尝试区分不是按类型控制,而是将类型名称区分为字符串。类似的东西;

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

另一方面,我想知道为什么你没有使用.Net内置支持多语言。

答案 1 :(得分:1)

嗯,依赖关系是程序架构的完美之处。 要明确:

假设您编写ReadTextForMySuperCoolLabel(..)因为您需要将某些特定内容转换为 控件属性,这些属性不会遇到您使用的其他控件。

如果这是真的,就没有办法避免你所说的依赖。使用直接分配,使用反射,使用其他东西......必须有某人,某处说: “这是一个MySuperControl,所以这个,这是另一个,所以那个”。

如果有一种方法可以概括属性赋值。例如,您的应用中的所有控件都具有Text属性。在这种情况下,可以使这些东西变得通用。

祝你好运。

答案 2 :(得分:0)

好吧,一种方法是通过使用依赖注入框架(如Castle Windsor)来延迟绑定所有类,或者通过创建类似这样的类来滚动自己的类:

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

这样您就不需要添加对SuperCool库的引用,只需将它包含在您的binry中。但是,我猜测SuperCool控件是在表单设计器中使用的,因此您可能无法像这样设置控件。

答案 3 :(得分:0)

您的问题实际上违反了Liskovs替换原则,因为您的翻译类必须单独处理每个派生类型。

我们知道winforms必须具有控件类型:容器和控件。容器包含多个控件,而控件只是一个控件;)

我们可以使用该知识来创建通用表单翻译器:

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);