Cum obțineți spațiul de nume rădăcină al unui ansamblu?

Dat fiind o instanță a System.Reflection.Assembly .

0

13 răspunsuri

Nu este posibil. Nimic nu specifică un spațiu de nume "Root". Spațiul de nume implicit din opțiuni este un lucru de studiu vizual, nu un lucru .net

0
adăugat
Răspunsul lui Roboblob Darren este corect din punct de vedere tehnic. Mina este utilă doar în aproximativ 95% din cazurile în care doriți să știți acest lucru în contextul construirii unui proiect în VS.
adăugat autor Lisa, sursa
Sub postul de la utilizatorul Lisa funcționează de fapt, astfel încât acest răspuns este marcat ca răspuns, dar fără un motiv corespunzător.
adăugat autor Roboblob, sursa

Ar putea exista orice număr de spații de nume într-o anume adunare, și nimic nu le cere tuturor să pornească de la o rădăcină comună. Ceea ce puteți face cel mai bine ar fi să reflectați asupra tuturor tipurilor dintr-un ansamblu și să creați o listă de spații de nume unice conținute în acestea.

0
adăugat

Există, de fapt, o modalitate indirectă de ao obține, enumerând numele resurselor manifeste ale adunării. Numele dorit se termină cu partea pe care o cunoașteți.

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

0
adăugat

Întrebarea pe care am avut-o că m-a aterizat aici a fost: "Dacă numesc codul de bibliotecă N metodele profunde și vreau spațiul de nume al Proiectului - de exemplu, aplicația MVC care rulează de fapt - cum pot obține asta?"

Un pic cam ciudat, dar poti apuca o stivuire si un filtru:

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

Tot ceea ce faceți este să obțineți stacktrace, să rulați metodele de la cel mai recent apelat la rădăcină și să filtrați sistemul. Odată ce găsește un apel sistem, știe că a dispărut prea mult și te întoarce în spațiul de nume imediat deasupra lui. Indiferent dacă executați un Test de unitate, o aplicație MVC sau un serviciu, containerul Sistem va fi așezat la un nivel mai adânc decât spațiul de nume rădăcină al Proiectului dvs., deci voila.

În unele situații în care codul sistemului este un intermediar (ca System.Task) de-a lungul traseului, acesta va reveni la un răspuns greșit. Scopul meu a fost de a lua, de exemplu, un cod de pornire și lăsați-l să găsească cu ușurință o clasă sau un controler sau orice altceva în spațiul de nume rădăcină, chiar dacă codul care face lucrarea se află într-o bibliotecă. Aceasta îndeplinește această sarcină.

Sunt sigur că poate fi îmbunătățită - sunt sigur că acest mod de a face lucrurile înnebunitoare poate fi îmbunătățit în multe feluri, iar îmbunătățirile sunt binevenite.

0
adăugat

Spațiile de nume nu au nimic de-a face cu ansamblurile - orice mapare între un spațiu de nume și clasele dintr-un ansamblu se datorează pur și simplu unei convenții de denumire (sau coincidență).

0
adăugat
În timp ce sunt de acord, merită menționat faptul că un proiect Visual Studio are un spațiu de nume implicit și dacă utilizați Visual Studio pentru a încorpora o resursă, atunci resursa respectivă a resurselor este derivată din spațiul de nume implicit și va apărea definită de ansamblul propriu dacă Utilizați întotdeauna Visual Studio pentru a construi ansamblul. Și să ne confruntăm cu asta este destul de comună.
adăugat autor Lisa, sursa

Ansamblurile nu au neapărat un spațiu de nume rădăcină. Spațiile de nume și ansamblurile sunt ortogonale.

Ceea ce probabil căutați în schimb este să găsiți un tip în acea adunare și apoi să aflați ce este spațiul său de nume.

Ar trebui să puteți realiza acest lucru utilizând elementul GetExportedTypes() și apoi utilizând proprietatea Spațiu de nume dintr-unul din mânerele de tip returnate.

Din nou, însă, nu există garanții că toate tipurile sunt în același spațiu de nume (sau chiar în aceeași ierarhie a spațiului de nume).

0
adăugat

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
adăugat

Am dat peste această dilemă de multe ori când vreau să încarc o resursă din actuala adunare prin fluxul de resurse manifest.

Faptul este că dacă încorporați un fișier ca resursă în ansamblul dvs. utilizând Visual Studio, numele său de resursă manifest va fi derivat din spațiul de nume implicit al ansamblului, așa cum este definit în proiectul Visual Studio.

Cea mai bună soluție cu care am venit (pentru a evita hardcoding-ul spațiului de nume implicit ca un șir undeva) este să vă asigurați că codul dvs. de încărcare a resurselor se desfășoară întotdeauna din interiorul unei clase care este și în spațiul de nume implicit și apoi următoarea abordare aproape generică Poate fi folosit.

Acest exemplu este încărcarea unei scheme încorporate.

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
adăugat
Au avut probleme cu rezoluția resurselor încorporate când numele ansamblului și "spațiul de nume rădăcină" al proiectului meu nu se potrivesc. Vă mulțumim pentru postul utile
adăugat autor Ivaylo Slavov, sursa
Nu puteți crea o clasă fără un spațiu de nume și utilizați typeof (DefaultNamespaceHelper) .Namespace?
adăugat autor drake7707, sursa
Acest cod funcționează de fapt. Mulțumiri!
adăugat autor Roboblob, sursa
GetType(frm).Namespace

frm is the startup Form

0
adăugat
Ce se întâmplă dacă formularul de pornire nu este în spațiul de nume rădăcină?
adăugat autor Patrick Hofman, sursa

Tocmai am creat o clasă internă goală numită Root și am pus-o în rădăcina proiectului (presupunând că acesta este spațiul dvs. de nume rădăcină). Apoi folosesc acest lucru oriunde am nevoie de spațiul de nume rădăcină:

typeof(Root).Namespace;

Sigur că sfârșesc cu un dosar neutilizat, dar e curat.

0
adăugat
Utile atunci când este nevoie de acest lucru în același ansamblu, dar nu doriți să-l codificați greu.
adăugat autor CSharper, sursa

Eu folosesc typeof (App) .Namespace în aplicația mea WPF. Clasa de aplicații este obligatorie pentru orice aplicație wpf și este localizată în rădăcină.

0
adăugat

Adăugând la toate celelalte răspunsuri aici, sperăm că fără a repeta informații, iată cum am rezolvat acest lucru folosind Linq. Situația mea este similară cu răspunsul lui Lisa.

Soluția mea vine cu următoarele avertismente:

  • Utilizați Visual Studio și aveți un spațiu Nomenclat Root definit pentru proiectul dvs., despre care presupunem că este ceea ce solicitați, deoarece utilizați termenul "spațiu de nume rădăcină"
  • Nu încorporați tipuri de interopuri din ansamblurile raportate
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
adăugat

Aici este o modalitate destul de simplă de a obține spațiul de nume rădăcină pentru un proiect de site web.

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

Aceasta verifică pur și simplu toate ansamblurile încărcate pentru tipul "MyProject" și returnează spațiul de nume rădăcină pentru tipul respectiv. Acest lucru este util pentru logare atunci când aveți mai multe proiecte web într-o singură soluție de partajare a unui sistem log. Sper că acest lucru îi ajută pe cineva.

0
adăugat