集会。。。内部和外部命名空间



这里有一个快速问题。我有一个程序集正在被一些开发人员重用,它包含各种功能,但从技术上讲,它被划分在表示功能逻辑块的各种名称空间中。

现在,它提供了尽可能少的公共名称空间。基本上,用户不应该知道(目前也不知道)他们试图使用的类正在使用哪个内部结构。

假设你有这个:

  • NS1

    • NS11
    • 111级
    • 112级
    • NS扩展
      • 扩展类1
    • NS12
  • NS2

基本上,用户知道他们使用FrameworkName.NS1来实现有关NS1的一般功能。现在,在这个简单的例子中,我已经将一个包含扩展方法的类放在了一个子空间扩展中,所以基本上,如果最终用户试图使用程序集,他必须真正了解DLL的内部结构才能知道扩展的存在(这是intellisense不会告诉你知道的例子之一)。

所以底线。。。现在我有了这个程序集,在内部(VS项目),我像通常一样将项目划分为逻辑文件夹,但我不让名称空间跟随文件夹。通过这种方式,程序集被划分为用户知道的逻辑块,而不必知道内部结构,也不需要知道可能有单独的命名空间用于扩展等等

现在,就我个人而言,我希望我能让代码的命名空间遵循我的文件夹结构,但在编译时以某种方式将这些子命名空间映射到主命名空间。

有可能以某种方式实现这种"重定向"吗?

简单地说,我希望能够在程序集外部将NS1.NS11.Class111公开为NS1.Class111,同时在程序集内部保持适当的结构。

如果您需要通过不同的命名空间提供对某些内部代码的第三方访问,我会将数据访问抽象到一个单独的程序集(取决于原始程序集)中,或者使用web服务来提供您希望他们访问的功能子集。

你可能可以对每个类的属性做一些事情,尽管我想它会变得非常混乱,非常快。

有几种方法可以考虑这个问题。最初来自VB.net背景,最近来自C#,我对这个话题有以下评论。

  1. VB中未采用文件夹\命名空间约定
  2. 您将如何解决代码版本控制和管理问题
  3. 如果引入其他c#开发人员来补充您的团队,他们可能会发现很难理解命名空间/文件夹的转移
  4. 您可以将父命名空间放在csproj属性中的应用程序"默认命名空间"下。这将允许您通过复制粘贴继承或源代码管理文件夹或子项目在项目之间共享这些公用工具(文件夹)。这允许NS1.Extensions和NS2.Extensions包含相同的代码
  5. 我不会担心"隐藏"API内部太多,除非它是一个特别敌对的技术环境。即使是"加密"方法也应该使用适当的公钥/私钥基础设施,以使其在设计上安全
  6. 如果你观察一下大多数框架是如何分解这些解决方案的,你会看到一系列项目,其中包括名称空间的所有代码,如"Core"、"Shared"、"Common"。这些开发人员中的大多数都非常聪明,所以如果这是他们做事的方式,我会效仿
  7. 您是否考虑过将金块部署到"共享网络文件夹"中,并设置所有开发人员将VS指向该位置
  8. 最后,我发现扩展和辅助方法很快就会变得非常稳定,所以代码不会有太大的变化。我把它们推到我的源代码管理中包含的文件夹/library/MyBusinessName/NameOfService1.0.0.0/。Nuget包使用的文件夹结构相同,所以我知道我的核心底层公司代码或框架的版本何时使用
  9. 最后,如果你要让你的代码沿着MVVM路径(流行)移动,并且你在依赖注入中看到了价值,那么你必须包括很多"接口"来帮助测试你的公共共享代码,这在一个单独的DLL/项目中要容易得多

就我个人而言,我曾与一个团队合作,该团队导入了他们在公司软件中引用的每一个东西的所有底层源代码,这样他们就可以"更改"任何东西。最后,它造成了一个不道德的构建复杂度,并在调试时吓了我一跳。Nuget提供了一个非常好且非常流行的模型,我在公司"共享"代码中采用了这个模型。如果我需要"推特"共享代码,我会在解决方案/项目中单独进行,测试、部署,并使用源代码管理或掘金来复制文件。

这里有一个想法:创建包装类供公共使用。它可能有点低效(尽管JIT可能会处理它),而且相对来说维护起来有点困难,但如果你担心你的公共API(你应该担心),它可能是一个不错的选择。在大多数情况下,连接几个调用不会引起任何问题,并且您将有一个与公共API相关的层,这可能会让您在外表后面犯下一些错误(例如,为了性能而违反一些好的软件设计规则)

你可以随心所欲地创建你的内部结构:

namespace Framework.Cool.Internal
{
    internal class BeansWeWantToCook
    {
        internal bool Cook()
        {
            // cooking process
        }
    }
}

然后使用您想要公开的名称空间为内部功能创建一个公共包装器:

namespace Framework.Cool
{
    public class Beans
    {
        // omitted code for brevity
        public bool Cook()
        {
            return _beansWeWantToCook.Cook();
        }
    }
}

这将创建一个非常传统的结构,这不会让任何想要浏览应用程序的类的人感到惊讶。

另一种选择是采用特定于项目的约定,比如将所有公共类都放在项目的根目录下。

顺便说一句,我不会对编译或构建时过程做任何有趣的事情。我认为这太令人困惑了,尤其是对新来的人来说。

最新更新