大会......内部和外部命名空间

时间:2013-12-02 10:47:33

标签: c# .net namespaces

这里有个问题。我有一个程序集被一些开发人员重用,它包含各种功能,但在技术上分为各种名称空间,代表逻辑功能块。

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

假设你有这个:

  • NS1

    • NS11
    • Class 111
    • Class 112
    • NS扩展程序
      • Extension Class 1
    • NS12
  • NS2

    • ...

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

所以底线...现在我已经有了这个程序集和内部(VS项目)我将项目划分为逻辑文件夹,就像通常那样,但我不让命名空间跟随文件夹。这样,程序集就分成了逻辑块,用户知道这些逻辑块不需要知道内部结构,也不需要知道扩展名可以有单独的命名空间等等。

现在,如果我可以让我的代码的命名空间遵循我的文件夹结构,但是在编译时以某种方式将这些子命名空间映射到主命名空间,我个人也喜欢它。

是否有可能以某种方式实现这种“重定向”?

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

3 个答案:

答案 0 :(得分:0)

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

你可能能够对每个类的属性做一些事情,虽然我想它会非常混乱,非常快。

答案 1 :(得分:0)

有几种方法可以考虑这一点。 最初来自VB.net背景和最近的C#我对这个主题有以下评论。

  1. VB中未采用文件夹\名称空间约定。
  2. 您将如何处理代码版本控制和管理。
  3. 如果引入其他c#开发人员来补充您的团队,他们可能会发现很难理解命名空间/文件夹转移。
  4. 您可以将父命名空间放在应用程序“默认命名空间”下的csproj属性中。这将允许您通过复制和粘贴继承或源控制文件夹或子项目在项目之间共享这些公用实用程序(文件夹)。这允许NS1.Extensions和NS2.Extensions包含相同的代码。
  5. 我不担心“隐藏”内部企业API太多,除非它是一个特别恶劣的技术环境。即使您的“加密”方法也应使用适当的公钥/私钥基础结构,以使其设计安全。
  6. 如果你看一下大多数框架如何分解解决方案,你会看到一系列项目,其中包括命名空间的所有代码,如“Core”,“Shared”,“Common”。这些开发人员中的大多数都非常聪明,所以如果这是他们做事的方式,我会遵循。
  7. 您是否考虑过将nugget部署到“共享网络文件夹”并设置所有开发人员将VS指向该位置?
  8. 最后我发现扩展和辅助方法非常快速地变得非常稳定,所以代码不会改变太多。我将它们推送到我的源代码控制 /library/MyBusinessName/NameOfService.1.0.0.0 / 中包含的文件夹中。与Nuget包使用的文件夹结构相同,因此我知道我的核心底层企业代码或框架的版本何时正在使用。
  9. 最后,如果您要让代码向下移动MVVM路径(受欢迎)并且您看到dependency injection中的值,那么您将需要包含大量“接口”帮助测试您的常见共享代码,这在单独的DLL / Project中更容易。
  10. 就我个人而言,我曾与一个团队合作,该团队为他们在公司软件中引用的每件事物导入了所有底层源代码,因此他们可以“改变”任何东西。在一天结束时,它创建了一个不圣洁的构建复杂程度,并在调试时吓坏了我的裤子。 Nuget提供了一个非常受欢迎的模型,我已经采用了企业“共享”代码。如果我需要“调整”共享代码,我会在解决方案/项目中单独执行,测试,部署它并使用源代码控制或块来复制文件。

答案 2 :(得分:0)

这是一个想法:为公共使用创建包装类。它可能有点低效(虽然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();
        }
    }
}

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

另一种选择是采用项目特定约定,例如将所有公共类保留在项目的根目录中。

顺便说一句,我不会对编译或构建时间程序做任何有趣的事情。我认为这对于新来者来说太麻烦了。