5

我刚看完 NDC 的 Bob Martin 的一集,他说页面顶部的 C# 中的“使用”指令很糟糕,因为它们在组件之间创建/暗示了紧密耦合。

有什么方法可以在不添加项目引用和 using 语句的情况下使用外部 .dll?

我记得 V6 曾经让您通过 ProgId 的字符串创建一个对象——我不确定这是我正在寻找的技术,但它是一个不需要项目引用即可使用的语言示例dll。

编辑:这是会议的链接。抱歉,演讲中没有确切的报价或分钟,我是凭记忆进行的。

4

5 回答 5

7

我相信 Bob Martin 实际上是指早期绑定和后期绑定。

在 .NET 中,后期绑定可以通过反射实现,更具体地说是 Activator 类,它允许使用文件名或程序集名称在外部程序集中创建类型。

通常,using 指令(而不是 using 语句)与直接引用外部程序集齐头并进。IE。添加对程序集的引用,然后添加 using 指令以避免在使用外部类型时需要键入完整的命名空间层次结构。

因此,如果您发现您的代码在顶部有大量 using 指令,那么您可能直接引用了许多其他类型,从而增加了代码对这些类型的耦合/依赖性。

我猜这就是鲍勃说他们不好的原因。“这真的很糟糕吗?”这个问题的答案。是一个非常主观的和上下文相关的。

但总的来说,组件的解耦几乎总是设计软件的一个很好的目标。这是因为它允许您更改系统的某些部分,而对系统的其余部分的影响最小。读过一两本 Bob Martins 的书,我想这就是他的意思。

于 2009-09-10T11:46:01.300 回答
6

using只是命名空间的快捷方式,它们不是对外部文件的引用。因此,这只是没有意义。

无论如何,可以做的是拥有一个接口 DLL(一个只有接口的 DLL),以便您动态加载和使用不同的程序集并创建可以转换为众所周知的接口的类型(通过反射)。这是放松外部引用同时保持强类型语言和早期绑定的好处的正确方法。

查看AssemblyAppDomain类以加载程序集,以及Activator以按名称创建类型实例。

于 2009-09-10T11:42:11.000 回答
6

不好的不是 using 语句本身——而是如果你得到太多的话。

诸如此类的语句using System;本身很少有问题,但是如果您在同一个代码文件中有很多(我会说超过 3-6 个,具体取决于哪些),则可能表明存在紧密耦合

您也可以将类似的经验法则应用于项目本身的引用数量。

紧密耦合的解决方案是对接口和依赖注入 (DI) 进行编程。

您可以从 VB 中记住的 ProgId 做事方式就是 COM 的实际操作。本质上,您使用该 ProgId 来获取对实现所需接口的实例的引用。缺点是这只在 COM 对象被普遍注册时才有效。还记得dll地狱吗?

您仍然可以使用某些 DI 风格应用相同的原理,只是现在接口是 .NET 类型并且未在 IDL 中定义,并且您需要某种 DI 容器来提供具体实现。

于 2009-09-10T11:53:05.110 回答
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]);
于 2009-09-10T11:47:06.243 回答
1

你可以通过反思来做你所指的事情。您可以在运行时加载程序集,并通过它反映以获取类等并动态调用它们。

就个人而言,我不会这样做以避免耦合。对我来说,这是对反射的不好使用,我更愿意将它添加到项目中并引用它,除非有特定的理由不这样做。反射增加了系统的开销,并且您没有获得编译时安全的优势。

于 2009-09-10T11:46:47.980 回答