我刚刚在NDC观看了Bob Martin的一集,他说在页面顶部的C#中使用“using”指令很糟糕,因为它们在组件之间产生/暗示的紧密耦合。
在没有添加项目引用和using语句的情况下,有什么方法可以使用外部.dll?
我记得V6曾经让你通过ProgId的字符串创建一个对象 - 我不确定这是我正在寻找的技术,但它是一个不需要项目参考的语言的例子使用DLL。
编辑:Here is a link to the conference。对不起我在演讲中没有确切的引用或分钟,我记得。
答案 0 :(得分:7)
我相信Bob Martin实际上指的是早期与晚期绑定。
在.NET中,后期绑定可以通过反射进行,更具体地说是Activator类,它允许使用文件名或程序集名称在外部程序集中创建类型。
通常,使用指令(而不是using语句)与直接引用外部程序集齐头并进。即。您添加对程序集的引用,然后添加using指令以避免在使用外部类型时需要键入完整的命名空间层次结构。
因此,如果您发现代码顶部有大量using指令,则可能直接引用许多其他类型,从而增加代码在这些类型上的耦合/依赖性。
我猜这就是鲍勃将它们称为坏的原因。问题的答案“这真的很糟糕吗?”是一个非常主观和依赖于语境的人。
总的来说,组件的分离几乎总是一个很好的目标,旨在设计软件。这是因为它允许您更改系统的各个部分,而对系统的其余部分影响最小。读完一两篇鲍勃·马丁的书后,我希望这就是他所得到的。
答案 1 :(得分:6)
using
只是命名空间的快捷方式,它们不是对外部文件的引用。因此,这真的没有意义。
无论如何,人们可以做的是拥有一个接口DLL(只有接口的DLL),这样你就可以动态加载和使用不同的程序集并创建可以转换为众所周知的接口的类型(通过反射)。这是放松外部引用的正确方法,同时保持强类型语言和早期绑定的好处。
答案 2 :(得分:6)
使用声明本身不是很糟糕 - 如果你得到太多的话。
诸如using System;
这样的陈述本身很少是一个问题,但是如果你在同一个代码文件中有很多(我会说超过3-6,取决于哪些),它可能是一个紧耦合指示。
您也可以将类似的经验法则应用于项目本身的引用数量。
紧耦合的解决方案是编程到接口和依赖注入(DI)。
你可以从VB中记住的ProgId做事方式就是COM在行动。本质上,您使用该ProgId来获取对实现所需接口的实例的引用。缺点是这只有在COM对象被普遍注册时才有效。还记得吗?
您仍然可以使用某些类型的DI来应用相同的原则,只是现在接口是.NET类型而没有在IDL中定义,并且您需要某种DI容器来提供具体的实现。
答案 3 :(得分:2)
你可以使用反射:
// Load the assembly
Assembly assembly = Assembly.LoadFrom(@"c:\path\Tools.dll");
// Select a type
Type type = assembly.GetType("Tools.Utility");
// invoke a method on this type
type.InvokeMember("SomeMethod", BindingFlags.Static, null, null, new object[0]);
答案 4 :(得分:1)
你可以通过反思来做你所指的事。您可以在运行时加载程序集,并通过它反映以获取类等,并动态调用它们。
就个人而言,我不会这样做,但要避免耦合。对我而言,这是对反射的错误使用,我宁愿将其添加到项目中并引用它,除非有特定原因不这样做。反射增加了系统的开销,并且您没有获得编译时安全性的优势。