Wie erhalten Sie den Root-Namespace einer Assembly?

Gegeben eine Instanz von System.Reflection.Assembly .

0
hinzugefügt bearbeitet
Ansichten: 2

13 Antworten

Nicht möglich. Nothing gibt einen "Root" -Namespace an. Der Standard-Namespace in den Optionen ist eine visuelle Studio-Sache, keine .net-Sache

0
hinzugefügt
@Roboblob Darrens Antwort ist technisch korrekt. Meins ist nur in den ungefähr 95% der Fälle nützlich, in denen Sie dies im Kontext des Aufbaus eines Projekts in VS wissen wollen.
hinzugefügt der Autor Lisa, Quelle
Unter dem Post von Benutzer Lisa funktioniert tatsächlich, so wird diese Antwort als Antwort aber ohne richtigen Grund markiert.
hinzugefügt der Autor Roboblob, Quelle

Es könnte eine beliebige Anzahl von Namespaces in einer gegebenen Assembly geben, und nichts erfordert, dass sie alle von einer gemeinsamen Wurzel ausgehen. Das Beste, was Sie tun könnten, wäre, über alle Typen in einer Assembly nachzudenken und eine Liste von darin enthaltenen eindeutigen Namespaces aufzubauen.

0
hinzugefügt

Es gibt tatsächlich einen indirekten Weg, um es zu bekommen, indem man die Namen der Manifest-Ressourcen der Versammlung aufzählt. Der gewünschte Name endet mit dem Teil, den du kennst.

Rather than repeat the code here, please see get Default namespace name for Assembly.GetManifestResourceStream() method

0
hinzugefügt

Die Frage, die mich hierher gebracht hat, war: "Wenn ich Bibliothekscode-N-Methoden tiefgründig nenne und den Namespace des Projekts möchte - zum Beispiel die MVC-App, die tatsächlich läuft - wie bekomme ich das?"

Ein wenig hacky, aber Sie können einfach einen Stacktrace greifen und filtern:

    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 dies macht den Stacktrace, führt die Methoden von zuletzt aufgerufen in root und filtert nach System. Sobald es einen Systemaufruf findet, weiß es, dass es zu weit gegangen ist und gibt den Namespace direkt darüber zurück. Unabhängig davon, ob Sie einen Komponententest, eine MVC-App oder einen Dienst ausführen, der Systemcontainer befindet sich 1 Stufe tiefer als der Root-Namespace Ihres Projekts, also voila.

In einigen Szenarien, in denen der Systemcode ein Vermittler (wie System.Task) ist, wird die falsche Antwort zurückgegeben. Mein Ziel war es, zum Beispiel Startup-Code zu nehmen und es leicht zu finden, eine Klasse oder Controller oder was auch immer im Stamm-Namespace, auch wenn der Code, der die Arbeit erledigt, in einer Bibliothek sitzt. Dies erfüllt diese Aufgabe.

Ich bin mir sicher, dass das verbessert werden kann - ich bin mir sicher, dass diese hacky Art der Dinge in vielerlei Hinsicht verbessert werden kann, und Verbesserungen sind willkommen.

0
hinzugefügt

Namespaces haben nichts mit Assemblys zu tun - jede Zuordnung zwischen einem Namespace und den Klassen in einer Assembly ist rein auf eine Namenskonvention (oder Koinzidenz) zurückzuführen.

0
hinzugefügt
Obwohl ich dem zustimme, sollte angemerkt werden, dass ein Visual Studio-Projekt über einen Standardnamespace verfügt und wenn Sie Visual Studio zum Einbetten einer Ressource verwenden, wird der Name der Manifestressource dieser Ressource vom Standardnamespace abgeleitet und von der Assembly selbst definiert verwenden Sie immer Visual Studio, um die Assembly zu erstellen. Und seien wir ehrlich, das ist ziemlich normal.
hinzugefügt der Autor Lisa, Quelle

Assemblys verfügen nicht unbedingt über einen Root-Namespace. Namespaces und Assemblies sind orthogonal.

Was Sie stattdessen suchen können, ist, einen Typ innerhalb dieser Assembly zu finden und dann herauszufinden, was der Namespace ist.

Sie sollten dies erreichen können, indem Sie das Member GetExportedTypes() verwenden und dann die Eigenschaft Namespace von einem der zurückgegebenen Type-Handles verwenden.

Auch hier besteht keine Garantie, dass sich alle Typen im selben Namespace (oder sogar in derselben Namespacehierarchie) befinden.

0
hinzugefügt

Get Types gives you a list of Type objects defined in the assembly. That object has a namespace property. Remember that an assembly can have multiple namespaces.

0
hinzugefügt

Ich bin oft auf dieses Dilemma gestoßen, wenn ich eine Ressource aus der aktuellen Assembly durch ihren Manifest-Ressourcenstrom laden möchte.

Wenn Sie eine Datei als Ressource in Ihrer Assembly mithilfe von Visual Studio einbetten, wird der Name der Manifest-Ressource vom Standard-Namespace der Assembly abgeleitet, der im Visual Studio-Projekt definiert wurde.

Die beste Lösung, die ich entwickelt habe (um den Standard-Namespace nicht als String zu codieren) besteht darin, einfach sicherzustellen, dass der Code zum Laden der Ressource IMMER aus einer Klasse stammt, die sich ebenfalls im Standard-Namespace und dem folgenden fast-generischen Ansatz befindet könnte genutzt werden.

In diesem Beispiel wird ein eingebettetes Schema geladen.

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
hinzugefügt
Hatte Probleme mit der eingebetteten Ressourcenauflösung, wenn der Assemblyname und der "Root-Namespace" meines Projekts nicht übereinstimmten. Danke für den hilfreichen Beitrag
hinzugefügt der Autor Ivaylo Slavov, Quelle
Können Sie keine Klasse ohne Namespace erstellen und typeof (DefaultNamespaceHelper) .Namespace verwenden?
hinzugefügt der Autor drake7707, Quelle
Dieser Code funktioniert tatsächlich. Vielen Dank!
hinzugefügt der Autor Roboblob, Quelle
GetType(frm).Namespace

frm is the startup Form

0
hinzugefügt
Was ist, wenn sich das Startformular nicht im Root-Namespace befindet?
hinzugefügt der Autor Patrick Hofman, Quelle

Ich habe gerade eine leere interne Klasse namens Root erstellt und sie in das Projekt-Root-Verzeichnis eingefügt (vorausgesetzt, dies ist Ihr Root-Namespace). Dann benutze ich das überall wo ich den Root Namespace brauche:

typeof(Root).Namespace;

Sicher, ich am Ende mit einer unbenutzten Datei, aber es ist sauber.

0
hinzugefügt
Nützlich, wenn Sie dies in derselben Baugruppe benötigen, aber nicht hart codieren möchten.
hinzugefügt der Autor CSharper, Quelle

Ich verwende typeof (App) .Namespace in meiner WPF-Anwendung. Die App-Klasse ist für jede WPF-Anwendung obligatorisch und befindet sich im Root-Verzeichnis.

0
hinzugefügt

Hinzufügen zu allen anderen Antworten hier, hoffentlich ohne Informationen zu wiederholen, hier ist, wie ich das mit Linq gelöst habe. Meine Situation ist Lisas Antwort ähnlich.

Meine Lösung enthält folgende Einschränkungen:

  • Sie verwenden Visual Studio und haben einen Root-Namespace für Ihr Projekt definiert, von dem ich annehme, dass Sie nach dem Begriff "root namespace"
  • fragen
  • Sie binden keine Interop-Typen aus referenzierten Assemblys ein
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
hinzugefügt

Hier als eine ziemlich einfache Möglichkeit, den Root-Namespace für ein Website-Projekt zu erhalten.

''' 
''' Returns the namespace of the currently running website '''
 
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

Dies überprüft einfach alle geladenen Assemblys auf den Typ "MyProject" und gibt den Root-Namespace für diesen Typ zurück. Dies ist nützlich für die Protokollierung, wenn Sie mehrere Webprojekte in einer einzigen Lösung haben, die sich ein Protokollsystem teilen. Hoffe, das hilft jemandem.

0
hinzugefügt