Question

Étant donné une instance de System.Reflection.Assembly .

Était-ce utile?

La solution

Pas possible. Rien ne spécifie un " Racine " espace de noms. L'espace de noms par défaut dans les options est une chose de Visual Studio, pas une chose de .net

Autres conseils

J'ai souvent rencontré ce dilemme lorsque je souhaite charger une ressource de l'assembly actuel à l'aide de son flux de ressources manifeste.

Le fait est que si vous intégrez un fichier en tant que ressource dans votre assemblage à l'aide de Visual Studio, son nom de ressource manifeste sera dérivé de l'espace de nom par défaut de l'assembly tel que défini dans le projet Visual Studio.

La meilleure solution que j'ai proposée (pour éviter de coder en dur l'espace de nom par défaut sous la forme d'une chaîne) est simplement de s'assurer que le code de chargement de votre ressource se passe TOUJOURS à l'intérieur d'une classe qui se trouve également dans l'espace de nom par défaut, puis à proximité. approche générique peut être utilisé.

Cet exemple charge un schéma incorporé.

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

Voir aussi: Comment obtenir un espace de noms d'un assembly?

Edit: Vous avez également remarqué une réponse très détaillée à la question à laquelle je répondais à http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/3a469f5d-8f55-4b25-ac25-4778f260bb7e

Une autre modification au cas où des personnes avec la même question viendraient chercher: Excellente idée de résoudre la question de chargement de ressources ici: Comment obtenir l'espace de nom par défaut du projet csproj (VS 2008)

Il peut y avoir un nombre quelconque d’espaces de nom dans un assemblage donné, et rien ne les oblige à tous partir d’une racine commune. Le mieux que vous puissiez faire serait de réfléchir à tous les types d’un assemblage et d’établir une liste d’espaces de noms uniques qui y sont contenus.

Les assemblys n’ont pas nécessairement d’espace de noms racine. Les espaces de noms et les assemblages sont orthogonaux.

Au lieu de cela, vous recherchez peut-être un type dans cette assemblée, puis son espace de noms.

Vous devriez pouvoir y parvenir en utilisant le membre GetExportedTypes () puis en utilisant la propriété Namespace à partir de l'un des descripteurs de type renvoyés.

Encore une fois, rien ne garantit que tous les types sont dans le même espace de noms (ou même dans la même hiérarchie d’espaces de noms).

Je viens de créer une classe interne vide appelée Root et de la placer dans la racine du projet (en supposant qu'il s'agisse de votre espace de noms racine). Ensuite, je l'utilise partout où j'ai besoin de l'espace de noms racine:

typeof(Root).Namespace;

Bien sûr, je me retrouve avec un fichier inutilisé, mais il est propre.

GetType(frm).Namespace

frm est le formulaire de démarrage

Obtenir les types vous donne un liste des tapez les objets définis dans l'assemblage. Cet objet a une propriété d'espace de noms. N'oubliez pas qu'un assemblage peut avoir plusieurs espaces de noms.

Les espaces de noms n'ont rien à voir avec les assemblages - tout mappage entre un espace de noms et les classes d'un assemblage est purement dû à une convention de dénomination (ou coïncidence).

Il existe en fait un moyen indirect de l'obtenir, en énumérant les noms des ressources manifestes de l'assembly. Le nom que vous souhaitez se termine par la partie de celle que vous connaissez.

Plutôt que de répéter le code ici, veuillez consulter get Nom de l'espace de noms par défaut pour la méthode Assembly.GetManifestResourceStream ()

J'utilise typeof (App) .Namespace dans mon application WPF. La classe app est obligatoire pour toutes les applications WPF et se trouve à la racine.

La question que je me posais ici était la suivante: "Si j'appelle les méthodes de code de bibliothèque N en profondeur et que je veux l'espace de noms du projet, par exemple l'application MVC en cours d'exécution, comment l'obtenir?"

Un petit hacky mais vous pouvez simplement récupérer un stacktrace et filtrer:

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

Tout ce que cela fait est de récupérer le stacktrace, de décomposer les méthodes les plus récemment appelées vers root et de filtrer pour System. Une fois qu'il a trouvé un appel système, il sait qu'il est allé trop loin et vous renvoie l'espace-noms immédiatement au-dessus de celui-ci. Que vous exécutiez un test unitaire, une application MVC ou un service, le conteneur System occupera un niveau plus profond que l'espace de nom racine de votre projet, donc le tour est joué.

Dans certains scénarios où le code système est un intermédiaire (comme System.Task) le long de la trace, la réponse ne sera pas correcte. Mon objectif était de prendre, par exemple, du code de démarrage et de le laisser trouver facilement une classe, un contrôleur ou tout autre élément de l'espace de noms racine, même si le code effectuant le travail se trouvait dans une bibliothèque. Ceci accomplit cette tâche.

Je suis sûr que cela peut être amélioré - je suis sûr que cette façon de faire simplifiée peut être améliorée de nombreuses manières, et les améliorations sont les bienvenues.

En ajoutant à toutes les autres réponses ici, j'espère, sans répéter l'information, voici comment j'ai résolu ce problème avec Linq. Ma situation est similaire à celle de Lisa.

Ma solution comporte les mises en garde suivantes:

  • Vous utilisez Visual Studio et un espace de noms racine a été défini pour votre projet. Je suppose que c'est ce que vous demandez, car vous utilisez le terme "espace de noms racine"
  • .
  • Vous n'incorporez pas de types interop à partir d'assemblys référencés
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
        )
)

Voici un moyen assez simple d'obtenir l'espace de noms racine d'un projet de site Web.

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

Ceci vérifie simplement tous les assemblys chargés pour le " MyProject " tapez et retourne l'espace de noms racine pour ce type. Cela est utile pour la journalisation lorsque plusieurs projets Web d'une même solution partagent un système de journalisation. J'espère que cela aide quelqu'un.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top