避免类中的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。
问题是:如何避免所有这些依赖关系,并且仍然有一个通用类来翻译程序?
也许您可以尝试不按类型来区分控件,而是按字符串的类型名称来区分控件。类似的东西;
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);