.net 如何获取程序集的根命名空间?

.net 如何获取程序集的根命名空间?,.net,reflection,.net,Reflection,给定System.Reflection.Assembly的实例。不可能。没有指定根命名空间。选项中的默认名称空间是visual studio,而不是.net。给定程序集中可以有任意数量的名称空间,并且不要求它们都从公共根开始。您所能做的最好的事情就是对程序集中的所有类型进行反思,并建立其中包含的唯一名称空间的列表 程序集不一定有根命名空间。名称空间和程序集是正交的 相反,您可能要寻找的是在该程序集中找到一个类型,然后找出它的名称空间是什么 您应该能够通过使用GetExportedTypes成员,

给定System.Reflection.Assembly的实例。

不可能。没有指定根命名空间。选项中的默认名称空间是visual studio,而不是.net。给定程序集中可以有任意数量的名称空间,并且不要求它们都从公共根开始。您所能做的最好的事情就是对程序集中的所有类型进行反思,并建立其中包含的唯一名称空间的列表

程序集不一定有根命名空间。名称空间和程序集是正交的

相反,您可能要寻找的是在该程序集中找到一个类型,然后找出它的名称空间是什么

您应该能够通过使用GetExportedTypes成员,然后使用其中一个返回的类型句柄中的Namespace属性来实现这一点


同样,不保证所有类型都在同一名称空间中,甚至在同一名称空间层次结构中。

提供程序集中定义的对象列表。该对象具有名称空间属性。请记住,一个程序集可以有多个名称空间。

名称空间与程序集无关-名称空间与程序集中的类之间的任何映射都纯粹是由于命名约定或巧合造成的。

当我想按其名称从当前程序集加载资源时,我多次遇到这种困境清单资源流

事实上,如果使用Visual Studio将文件作为资源嵌入程序集中,则其清单资源名称将从Visual Studio项目中定义的程序集的默认命名空间派生

我提出的避免将默认名称空间硬编码为字符串的最佳解决方案是,确保资源加载代码总是在默认名称空间中的类中进行,然后可以使用以下近似通用的方法

此示例正在加载嵌入式架构

XmlSchema mySchema;
string resourceName = "MyEmbeddedSchema.xsd";
string resourcesFolderName = "Serialisation";
string manifestResourceName = string.Format("{0}.{1}.{2}",
    this.GetType().Namespace, resourcesFolderName, resourceName);
using (Stream schemaStream = currentAssembly.GetManifestResourceStream(manifestResourceName))
    mySchema = XmlSchema.Read(schemaStream, errorHandler);
另见:

编辑:我还注意到了我现在回答的问题的一个非常详细的答案

另一个编辑,以防有相同问题的人来看:解决资源加载问题的好主意:


frm是启动表单

实际上有一种间接的方法可以获得它,方法是枚举程序集清单资源的名称。你想要的名字以你知道的部分结尾


不要在这里重复代码,请参见

我刚刚创建了一个名为Root的空内部类,并将其放在项目根中,假设这是您的根命名空间。然后,我在需要根命名空间的任何地方都使用此名称空间:

typeof(Root).Namespace;
当然,我最终会得到一个未使用的文件,但它是干净的。

我在WPF应用程序中使用typeofApp.Namespace。
App类对于任何WPF应用程序都是必需的,并且它位于根目录中。

我在这里遇到的问题是,如果我调用库代码N方法,并且想要项目的名称空间(例如实际运行的MVC应用程序),我如何获得该名称空间

有点黑,但你可以抓取stacktrace和过滤器:

    public static string GetRootNamespace()
    {
        StackTrace stackTrace = new StackTrace();
        StackFrame[] stackFrames = stackTrace.GetFrames();
        string ns = null;
        foreach(var frame in stackFrames)
        {
            string _ns = frame.GetMethod().DeclaringType.Namespace;
            int indexPeriod = _ns.IndexOf('.');
            string rootNs = _ns;
            if (indexPeriod > 0)
                rootNs = _ns.Substring(0, indexPeriod);

            if (rootNs == "System")
                break;
            ns = _ns;
        }

        return ns;
    }
所有这些工作都是获取stacktrace,运行最近调用到root的方法,并对系统进行过滤。一旦它找到一个系统调用,它就知道它做得太过分了,并返回它上面的名称空间。无论您运行的是单元测试、MVC应用程序还是服务,系统容器都将比项目的根命名空间更深一层,所以瞧

在某些场景中,系统代码是一个类似System.Task的中介,沿着跟踪这将返回错误的答案。我的目标是以一些启动代码为例,让它轻松地在根命名空间中找到类或控制器或任何东西,即使执行该工作的代码位于库中。这就完成了这项任务


我确信这是可以改进的-我确信这种黑客的做事方式可以在很多方面得到改进,而且改进是受欢迎的。

在这里添加所有其他答案,希望没有重复信息,下面是我如何使用Linq解决这一问题的。我的情况与丽莎的回答相似

我的解决方案附带以下警告:

您正在使用VisualStudio,并且为您的项目定义了一个根命名空间,我假设这就是您所要求的,因为您使用了术语根命名空间 您没有从引用的程序集嵌入互操作类型 Dim baseNamespace=String.Join.c, Me.GetType.Assembly.ManifestModule.GetTypes。 选择FunctionType作为类型 返回类型.Namespace.Split.c 端函数 . AggregateFunctionseed作为字符串,splitNamespace作为字符串 返回seed.IntersectsplitNamespace.ToArray 端函数
这里是获取网站项目根命名空间的一种非常简单的方法

''' <summary>
''' Returns the namespace of the currently running website
''' </summary>
Public Function GetWebsiteRootNamespace() As String
    For Each Asm In AppDomain.CurrentDomain.GetAssemblies()
        If Asm Is Nothing OrElse Asm.IsDynamic Then Continue For

        For Each Typ In Asm.GetTypes
            If Typ Is Nothing OrElse Typ.Name Is Nothing Then Continue For
            If Typ.Name = "MyProject" Then Return Typ.Namespace.Split("."c)(0)
        Next
    Next

    Return Nothing
End Function
这只是检查所有
为MyProject类型加载的程序集,并返回该类型的根命名空间。当一个解决方案中有多个web项目共享一个日志系统时,这对于日志记录非常有用。希望这对某人有所帮助。

虽然我同意,值得注意的是,VisualStudio项目有一个默认名称空间,如果使用VisualStudio嵌入资源,则该资源的清单资源名称派生自默认名称空间,并且如果始终使用VisualStudio构建程序集,则该名称似乎由程序集本身定义。让我们面对现实吧,这是很常见的。下面用户Lisa的帖子确实有效,所以这个答案被标记为答案,但没有适当的理由。@Roboblob Darren的答案在技术上是正确的。我的观点只在95%左右的情况下有用,在这种情况下,你想在构建项目的背景下了解这一点,而不是仅仅因为想象力的失败而不可能。看,可能吧。请参阅。从Lisa的回答来看,这是一个.NET问题。当程序集名称与我的项目的根命名空间不匹配时,我在嵌入式资源解析方面遇到了问题。感谢您提供的帮助。您是否可以创建一个没有命名空间的类并使用typeofDefaultNamespaceHelper.namespace?此答案不应获得支持,因为它会误导那些搜索实际问题答案的人。这个答案只获取您所在类的名称空间。它绝对没有得到当前程序集的根命名空间,这就是问题所在。Darren的答案是正确的。@Neo你所描述的所有警告都已经在答案中写好了。当然,它回答了一个不同的问题,但人们来到这里试图回答我正在回答的问题。这对想知道如何找到所属类的命名空间的人很有帮助。如果启动窗体不在根命名空间中该怎么办?在同一程序集中需要它时很有用,但不想硬编码它。
''' <summary>
''' Returns the namespace of the currently running website
''' </summary>
Public Function GetWebsiteRootNamespace() As String
    For Each Asm In AppDomain.CurrentDomain.GetAssemblies()
        If Asm Is Nothing OrElse Asm.IsDynamic Then Continue For

        For Each Typ In Asm.GetTypes
            If Typ Is Nothing OrElse Typ.Name Is Nothing Then Continue For
            If Typ.Name = "MyProject" Then Return Typ.Namespace.Split("."c)(0)
        Next
    Next

    Return Nothing
End Function