如何获得程序集的根命名空间?

时间:2008-09-18 20:02:46

标签: .net reflection

给出System.Reflection.Assembly

的实例

13 个答案:

答案 0 :(得分:56)

当我想通过其清单资源流从当前程序集加载资源时,我经常遇到这种困境。

事实是,如果使用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);

另请参阅:How to get Namespace of an Assembly?

编辑:还注意到我在http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/3a469f5d-8f55-4b25-ac25-4778f260bb7e

回答的问题的非常详细的答案

另一个编辑,以防有相同问题的人来看:在这里解决资源加载问题的好主意:How get the default namespace of project csproj (VS 2008)

答案 1 :(得分:38)

不可能。 Nothing指定“Root”命名空间。选项中的默认命名空间是视觉工作室的东西,而不是.net的东西

答案 2 :(得分:10)

给定程序集中可能有任意数量的命名空间,并且没有任何东西要求它们都从公共根开始。您可以做的最好的事情是反映程序集中的所有类型,并构建其中包含的唯一命名空间列表。

答案 3 :(得分:5)

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

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

您应该能够通过使用GetExportedTypes()成员,然后使用其中一个返回的Type句柄中的Namespace属性来实现此目的。

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

答案 4 :(得分:4)

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

typeof(Root).Namespace;

当然我最终得到了一个未使用的文件,但它很干净。

答案 5 :(得分:2)

GetType(frm).Namespace

frm是启动表格

答案 6 :(得分:1)

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

答案 7 :(得分:0)

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

答案 8 :(得分:0)

通过枚举程序集的清单资源的名称,实际上有一种间接的方式来获取它。您想要的名称以您知道的部分结束。

请参阅get Default namespace name for Assembly.GetManifestResourceStream() method

,而不是在此处重复代码

答案 9 :(得分:0)

我在WPF应用程序中使用typeof(App).Namespace。 App类对于任何WPF应用程序都是必需的,它位于root。

答案 10 :(得分:0)

我在这里遇到的问题是,“如果我深入调用库代码N方法并希望项目的命名空间 - 例如实际运行的MVC应用程序 - 我该如何获得?”

有点hacky,但你可以抓住一个堆栈跟踪并过滤:

    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;
    }

所有这一切都是获取堆栈跟踪,从最近调用的方法运行方法到root,并过滤System。一旦找到一个系统调用它就知道它已经走得太远了,并返回它上面的命名空间。无论您是运行单元测试,MVC应用程序还是服务,系统容器将比项目的根命名空间深一层,所以瞧。

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

我确信可以改进 - 我确信这种做事方式可以通过多种方式得到改善,并且欢迎改进。

答案 11 :(得分:0)

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

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

  • 您正在使用Visual Studio并为您的项目定义了一个根名称空间,我认为这是您要求的,因为您使用了术语" root namespace"
  • 您未从引用的程序集中嵌入互操作类型
Dim baseNamespace = String.Join("."c,
    Me.GetType().Assembly.ManifestModule.GetTypes().
        Select(Function(type As Type)
                    Return type.Namespace.Split("."c)
                End Function
        ).
        Aggregate(Function(seed As String(), splitNamespace As String())
                        Return seed.Intersect(splitNamespace).ToArray()
                    End Function
        )
)

答案 12 :(得分:0)

这是获取网站项目的根命名空间的一种相当简单的方法。

''' <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项目时,这对于日志记录非常有用。希望这有助于某人。