【问题标题】:Best Way to Reuse Code When Using Visual Studio?使用 Visual Studio 时重用代码的最佳方式?
【发布时间】:2010-09-07 06:39:11
【问题描述】:

我尝试了两种不同的代码重用方法。我有一个包含类库项目的解决方案,其中包含我在几乎每个我工作的项目中重用的通用代码。当我开始着手一个新项目时,我将通过以下两种方式之一重用此代码库中的代码:

  1. 我已经尝试将我需要的项目从这个代码库引入到我的项目中。
  2. 我还尝试编译为 .dll 并从当前解决方案的根目录中的文件夹中引用 .dll。

虽然第二种方法实施起来似乎更容易、更轻松,但我总是发现自己对原始代码进行了一些小调整,以使其适合我当前项目的上下文。

我知道这是一个有点含糊的问题,但是有没有人在新的解决方案上使用其他重用类库的方法取得成功?

【问题讨论】:

    标签: .net visual-studio


    【解决方案1】:

    简而言之,您所做的是对的,您希望将通用代码移至类库 (DLL) 中,然后在任何需要其逻辑的项目中引用它。

    你出错的地方是你没有维护它。如果您需要进行一些“调整”,subclass 您现有的代码并对其进行扩展,请不要更改它。如果需要进行重大更改,请重新考虑设计。

    【讨论】:

      【解决方案2】:

      你提到的两种方式我都做了。我喜欢第二个,但就像你说的那样,当你更新那个库时有点乏味。

      我使用的另一种方法是选择一个中心位置来保存您的库。然后添加一个带有字符串值的注册表项以指向该目录。添加引用时,您的所有库都将显示在 .net 选项卡下,就像这些库位于 GAC 中一样。然后,您可以发出构建后命令以将库构建到该中心位置。

      这是注册表项,更改 CompanyName 和目录:

      [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders\ComapnyName]
      @="C:\\CentralLocation"
      

      【讨论】:

        【解决方案3】:

        我喜欢将我所有的泛型类都写成这样:泛型。我尽可能让它们独立于应用程序,并试图让它们甚至不知道打字。如果我创建一个花哨的 Tree 类,我将使用泛型将其创建为 Tree ,以便我可以在该类中使用我想要的任何类型。如果我需要使用 Tree 来保存 GameCharacter 对象,我可以实例化 Tree,但如果我正在编写业务应用程序,我可以将其用作 Tree

        如果您发现自己更改了重用库以匹配您的项目,请尝试降低它们的具体性,而是从您的实际项目中的库基类派生。将所有通用逻辑放在库类中,对于特定于应用程序的部分,创建一个派生类并在该派生类中实现它们的逻辑。

        就解决方案组织而言,我将重用库作为一个单独的项目保存在一个公共文件夹中,并将该项目包含在我创建的任何解决方案中,这样我可以轻松地引用它,但也可以从任何我的应用程序的解决方案。

        【讨论】:

          【解决方案4】:

          我不使用 Visual Studio 或 .NET,但它认为这个问题在所有程序员中都很常见,所以我想我会尝试解决它。​​

          当我们尝试将通用代码提取到单独的库中时,我们遇到了类似的问题。一开始可能没问题,但最终会有一个客户需要一些新功能并需要对库进行更改。这总是会导致其他一些客户出现问题,造成巨大的混乱。除非您有很好的方法来对库文件进行版本控制,否则这是一个很难解决的问题。

          最后,您最好将源文件复制并粘贴到您的新项目中。是的,这违反了 DRY(不要重复自己)原则,但是您避免了很多与公共库创建的依赖项相关的问题。

          【讨论】:

            【解决方案5】:

            您真正需要做的是使用某种源代码控制软件,例如:

            • 您在一个项目中所做的任何更改都将反映在所有项目中,而不会丢失参考完整性
            • 您可以选择保留多个版本的库并引用特定版本,而不是费力地弄清楚哪个项目使用哪个版本

            只需确保您手头有单元测试,以确保您之前的项目不会受到您对库所做的任何更改的影响或仅受到轻微影响。

            祝你好运!

            【讨论】:

            • 我只知道一种支持共享文件的源代码控制产品。我喜欢它,但大多数人认为大声说出来是一个肮脏的词。
            • @Ian 我还是希望你这么说。视觉源安全吗?哈哈。
            • 拜托,我们是混血儿!
            【解决方案6】:

            @Outlaw
            如果您需要复制代码并进行特定于应用程序的更改,那么该代码不是通用的。应该对其进行重构,以便通用功能保留在通用库中,并且应将特定于应用程序的功能添加到该应用程序代码库中的子类中。

            对每个特定于应用程序的版本使用带有分支的版本控制有助于解决集成问题 - 在分支中进行更改,然后在将它们合并回主干之前使用其他应用程序对其进行测试。如果您不想设置自己的,本网站上有几个关于良好的免费在线源代码控制主机的问题。

            【讨论】:

              【解决方案7】:

              Ayende Rahien 的Rhino Tools 中有一些非常好的可重用代码。看看他是如何实现各种通用代码的,看看它是如何组织的。

              【讨论】:

                【解决方案8】:

                这个想法很好 - 将您的代码放在一个通用 dll 中并引用它。我们广泛使用这种方法并且它有效。显然有些项目最终会失去同步,所以我们这样做的方式是这样的:

                • 最不具体,如果您可以使用泛型类型,那么就这样做。例如,如果您想要一个处理空值或空值的函数,并且

                返回一些东西,实现 NullConvert(o as object, subst as object) as object 优于 NullConvert(o as object, String) as

                字符串。然后,您可以添加其他类型,使签名保持不变。但是,如果未处理类型,请在方法中具体说明并为未处理的类型引发异常 - 不要让它有机会工作。在上面的示例中,检查返回值的类型并检查您的实现是否处理该类型。

                • 在命名空间中按类型对函数进行分组; MyGeneric.DateFns、MyGeneric.StringFns、MyGeneric.Comms 等。

                • 一旦使用了类或方法,就不要更改功能,这样做可能不安全。将它们标记为已弃用并包含 cmets 以指示已放置更新/更好的类的位置。

                • 您可能会考虑两个或多个库,例如,基础库中的通用方法和类,以及特定领域的类和

                在另一个库(更高级别)中使用通用方法(来自基础库)的函数。这样,基础库就不需要一直更改。

                • 考虑使用“实现”而不是类。例如,如果您有一个处理 ArrayList 的函数,请将

                你的方法的参数来代替 iList。然后你也可以使用其他列表类型,只要它们在其中实现 iList。

                • 避免引入细节,例如显式驱动程序 (Oracle 8.x)。把它包在别的东西里,所以如果它改变了,改变

                包装对象的内部,而不是对象本身。

                • 了解如何使用反射。假设您需要一个函数来从对象数组中获取不同的值。你可以使用反射和

                然后传递您需要区分的属性名称; GetDistinct(MyList 作为 iList,“名称”)作为 List(字符串)。你的代码可能看起来

                通过反射调用名为“名称”的参数(涉及到小的性能损失)。

                • 了解如何编写扩展(组件模型)。例如,如果您正在编写一个始终返回特定格式的函数

                date,把函数变成扩展函数。明智地命名,如果您的公司名称是 ABC,那么例如使用 ABCDateFormat 来区分您的函数和 MS 函数。

                这里应该做的事情太多了。你是朝着正确方向迈出的一步。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-07-12
                  • 2011-05-02
                  • 1970-01-01
                  • 2011-09-08
                  • 1970-01-01
                  相关资源
                  最近更新 更多