“使用”的替代方案是C# 中的指令关键字?
我刚刚在 NDC 看完 Bob Martin 的一集,他说页面顶部的 C# 中的“使用”指令很糟糕,因为它们在组件之间创建/暗示了紧密的耦合。
有什么方法可以在不添加项目引用和 using 语句的情况下使用外部 .dll?
我记得 V6 曾经让你通过 ProgId 的字符串创建一个对象——我不确定这就是我正在寻找的技术,但它是一个不需要项目引用就可以使用dll。
编辑:这是会议的链接。抱歉,我在演示中没有确切的引述或分钟,我只是凭记忆。
I just finished watching an episode of Bob Martin at NDC where he said "using" directives in C# at the top of a page are bad because of the tight coupling they create/imply between components.
What way are there to use external .dlls without adding a project reference and a using statement?
I remember V6 used to let you create an object by the string of the ProgId--I'm not sure that's the technique I'm looking for, but it's an example of a language that didn't need a project reference to use a dll.
EDIT: Here is a link to the conference. Sorry I don't have the exact quote or minute in the presenation, I'm going by memory.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我相信鲍勃·马丁实际上指的是早期绑定与后期绑定。
在 .NET 中,后期绑定可以通过反射实现,更具体地说,Activator 类允许使用文件名或程序集名称在外部程序集中创建类型。
通常,using 指令(而不是 using 语句)与直接引用外部程序集密切相关。 IE。您添加对程序集的引用,然后添加 using 指令,以避免在使用外部类型时需要键入完整的命名空间层次结构。
因此,如果您发现代码顶部有大量 using 指令,则您可能直接引用许多其他类型,从而增加了代码对这些类型的耦合/依赖性。
我猜这就是鲍勃称他们为坏人的原因。 “这真的很糟糕吗?”这个问题的答案是一个非常主观且依赖于上下文的问题。
但总的来说,组件的解耦几乎总是软件设计中的一个很好的目标。这是因为它允许您更改系统的某些部分,而对系统其余部分的影响最小。读过鲍勃·马丁的一两本书后,我想这就是他的意思。
I believe Bob Martin is actually referring to early versus late binding.
In .NET late binding is possible through reflection and more specifically the Activator class that allows creation of a type in an external assembly using a filename or assembly name.
Normally, using directives (not the using statement) go hand in hand with directly referencing an external assembly. ie. You add a reference to an assembly and then add using directives to avoid needing to type the full namespace hierarchy when you use the external types.
So if you find your code has a large number of using directives at the top, it is possible that you are referencing many other types directly and so increasing the coupling/dependency of your code on these types.
I would guess this is why Bob is referring to them as bad. The answer to the question "is this actually bad?" is a very subjective and context dependent one.
In general though, de-coupling of components is almost always a good goal to aim for in designing software. This is because it allows you to change parts of your system with minimal impact on the rest of the system. Having read one or two of Bob Martins books, I would expect this is what he is getting at.
糟糕的并不是 using 语句本身,而是使用太多的语句。
像
using System;
这样的语句本身很少有问题,但是如果同一个代码文件中有很多语句(我想说超过 3-6 个,具体取决于哪些语句),则可能会出现问题是紧密耦合的标志。您也可以将类似的经验法则应用于项目本身的引用数量。
紧耦合的解决方案是接口编程和依赖注入 (DI)。
您在 VB 中所记得的 ProgId 执行操作的方式就是 COM 的实际操作。本质上,您使用该 ProgId 来获取对实现所需接口的实例的引用。缺点是这只有在 COM 对象被普遍注册时才有效。还记得dll地狱吗?
您仍然可以使用某些 DI 风格来应用相同的原则,只是现在接口是 .NET 类型并且未在 IDL 中定义,并且您需要某种 DI 容器来提供具体实现。
It's not the using statement itself that is bad - it's if you get too many of them.
A statement such as
using System;
is rarely a problem in itself, but if you have lots (I'd say more than 3-6, depending on which ones) in the same code file, it could be an indication of tight coupling.You could just as well apply a similar rule of thumb to the number of references in a project itself.
The solution to tight coupling is programming to interfaces and Dependency Injection (DI).
The ProgId way of doing things that you can remember from VB was simply COM in action. In essence, you used that ProgId to get a reference to an instance that implemented the desired interface. The downside was that this only worked when the COM object was universally registered. Remember dll hell?
You can still apply the same principle using certain flavors of DI, only that now the interface is a .NET type and not defined in IDL, and you need some sort of DI Container to supply the concrete implementation.
using
只是命名空间的快捷方式,它们不是对外部文件的引用。因此,这实际上没有意义。无论如何,我们可以做的就是拥有一个接口 DLL(一种仅具有接口的 DLL),以便您动态加载和使用不同的程序集并创建可以转换为众所周知的接口的类型(通过反射)。这是放松外部引用的正确方法,同时保留强类型语言和早期绑定的优点。
查看 程序集 和 AppDomain 类来加载程序集,以及 Activator 按名称创建类型实例。
using
is just a shortcut to namespaces, they are not references to external files. Therefore, this is just not really making sense.Anyways, what one can do is have an interface DLL (a DLL with only interfaces), so that you dynamically load and use different assemblies and create types (through reflection) which you can cast to the well-known interfaces. This is the proper way of loosening external references while keeping the benefits of the strongly typed language and early binding.
Have a look at the Assembly and AppDomain classes to load assemblies, and Activator to create type instances by name.
您可以使用反射:
You could use reflection:
你可以通过反思来做你所指的事情。您可以在运行时加载程序集,并通过它反映以获取类等并动态调用它们。
就我个人而言,为了避免耦合,我不会这样做。对我来说,这是对反射的错误使用,我宁愿将其添加到项目中并引用它,除非有特定原因不这样做。反射会增加系统的开销,并且您无法获得编译时安全性的优势。
You can do what you are referring to through reflection. You can load the assembly at runtime, and reflect through it to get the classes etc. and call them dynamically.
Personally, I wouldn't do this though to avoid coupling. To me that is a bad use of reflection, and I would much rather add it to the project and reference it, unless there is a specific reason why not to do so. Reflection adds overhead to the system, and you don't get the advantage of compile time safety.