How do you get the root namespace of an assembly?

前端 未结 13 1987
后悔当初
后悔当初 2020-12-01 11:41

Given an instance of System.Reflection.Assembly.

相关标签:
13条回答
  • 2020-12-01 12:22

    Not possible. Nothing specifies a "Root" namespace. The default namespace in the options is a visual studio thing, not a .net thing

    0 讨论(0)
  • 2020-12-01 12:22

    The question I had that landed me here was, "If I call library code N methods deep and want the namespace of the Project - for example the MVC app that's actually running - how do I get that?"

    A little hacky but you can just grab a stacktrace and filter:

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

    All this is doing is getting the stacktrace, running down the methods from most recently called to root, and filtering for System. Once it finds a System call it knows it's gone too far, and returns you the namespace immediately above it. Whether you're running a Unit Test, an MVC App, or a Service, the System container is going to be sitting 1 level deeper than the root namespace of your Project, so voila.

    In some scenarios where System code is an intermediary (like System.Task) along the trace this is going to return the wrong answer. My goal was to take for example some startup code and let it easily find a class or Controller or whatever in the root Namespace, even if the code doing the work sits out in a library. This accomplishes that task.

    I'm sure that can be improved - I'm sure this hacky way of doing things can be improved in many ways, and improvements are welcome.

    0 讨论(0)
  • I have come across this dilemma plenty of times when I want to load a resource from the current assembly by its manifest resource stream.

    The fact is that if you embed a file as a resource in your assembly using Visual Studio its manifest resource name will be derived from the default namespace of the assembly as defined in the Visual Studio project.

    The best solution I've come up with (to avoid hardcoding the default namespace as a string somewhere) is to simply ensure your resource loading code is ALWAYS happening from inside a class that's also in the default namespace and then the following near-generic approach may be used.

    This example is loading an embedded schema.

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

    See also: How to get Namespace of an Assembly?

    Edit: Also noticed a very detailed answer to the question I'm answering at http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/3a469f5d-8f55-4b25-ac25-4778f260bb7e

    Another edit in case people with same question come looking: Excellent idea to solve the resource-loading question here: How get the default namespace of project csproj (VS 2008)

    0 讨论(0)
  • 2020-12-01 12:25

    Adding to all the other answers here, hopefully without repeating information, here is how I solved this using Linq. My situation is similar to Lisa's answer.

    My solution comes with the following caveats:

    • You're using Visual Studio and have a Root Namespace defined for your project, which I assume is what you're asking for since you use the term "root namespace"
    • You're not embedding interop types from referenced assemblies
    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
            )
    )
    
    0 讨论(0)
  • 2020-12-01 12:26

    I use typeof(App).Namespace in my WPF application. App class is mandatory for any WPF application and it's located in root.

    0 讨论(0)
  • 2020-12-01 12:28

    Here as a rather simple way to get the root namespace for a website project.

    ''' <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
    

    This simply checks all the loaded assemblies for the "MyProject" type and returns the root namespace for that type. This is useful for logging when you have multiple web projects in a single solution sharing a log system. Hope this helps someone.

    0 讨论(0)
提交回复
热议问题