避免类中的dll依赖项

本文关键字:dll 依赖 | 更新日期: 2023-09-27 18:29:41

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

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

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

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

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

避免类中的dll依赖项

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

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

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

依赖关系是程序体系结构的核心。需要明确的是:

假设您编写ReadTextForMySuperCoolLabel(..)是因为您需要将一些特定的控件属性转换为,而这些属性不可能转换为您使用的其他控件。

如果这是真的,就没有办法避免你所说的依赖性。使用你的直接分配,使用反思,使用其他东西。。。一定有人在某处说:"这是一个MySuperControl,所以这个,这是另一个,所以那个"。

如果有一种方法可以推广属性分配。例如,应用程序中的所有控件都可以具有Text属性。在这种情况下,可以使内容变得通用。

祝你好运。

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

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

这样,您就不需要添加对SuperCool库的引用,只需将其包含在您的垃圾箱中即可。然而,我猜SuperCool控件是在表单设计器中使用的,所以您可能无法像这样安装控件。

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

我们知道winforms有两种类型的控件:Containers和controls。一个容器包含多个控件,而一个控件只是一个控件;)

我们可以使用这个知识来创建一个通用的表单翻译器:

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.
    }
}

它查找字符串,如:

  • 表格1.MyGroupPanel.Label1
  • 表单1.MyTextBox

翻译使用:

var translator = new UniversalFormTranslater();
translator.TranslateForm(form1);