Como você obtém o namespace raiz de uma montagem?

Dada uma instância de System.Reflection.Assembly .

0
adicionado editado
Visualizações: 1

13 Respostas

Não é possivel. Nada especifica um namespace "raiz". O namespace padrão nas opções é uma coisa de visual studio, não uma coisa .net

0
adicionado
@Roboblob A resposta de Darren está tecnicamente correta. O meu é meramente útil nos 95% ou mais dos casos em que você deseja saber isso no contexto da construção de um projeto no VS.
adicionado o autor Lisa, fonte
Abaixo do post do usuário Lisa realmente funciona, então esta resposta está marcada como resposta, mas sem o devido motivo.
adicionado o autor Roboblob, fonte

Pode haver qualquer número de namespaces em um determinado assembly, e nada requer que todos eles iniciem a partir de uma raiz comum. O melhor que você poderia fazer seria refletir sobre todos os tipos em uma montagem e criar uma lista de namespaces exclusivos contidos nela.

0
adicionado

Na verdade, existe uma maneira indireta de obtê-lo, enumerando os nomes dos recursos de manifesto do assembly. O nome que você quer termina com a parte que você conhece.

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

0
adicionado

A pergunta que me levou foi "Se eu chamar profundamente os métodos do código N da biblioteca e quiser o namespace do Projeto - por exemplo, o aplicativo MVC que está sendo executado - como obtenho isso?"

Um pouco hacky, mas você pode simplesmente pegar um stacktrace e filtrar:

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

Tudo o que isso está fazendo é obter o stacktrace, executando os métodos mais recentemente chamados para root e filtrando para System. Depois de encontrar uma chamada do Sistema, ela sabe que foi longe demais e retorna o namespace imediatamente acima dela. Se você estiver executando um Teste de Unidade, um Aplicativo MVC ou um Serviço, o contêiner do Sistema ficará 1 nível mais profundo do que o namespace raiz do seu Projeto, portanto voila.

Em alguns cenários onde o código do sistema é um intermediário (como System.Task) ao longo do rastreamento isso retornará a resposta errada. Meu objetivo era pegar, por exemplo, algum código de inicialização e deixá-lo localizar facilmente uma classe ou um Controller ou qualquer outra coisa no namespace da raiz, mesmo que o código que executa o trabalho esteja em uma biblioteca. Isso realiza essa tarefa.

Tenho certeza de que isso pode ser melhorado - tenho certeza de que essa maneira hacker de fazer as coisas pode ser melhorada de várias maneiras, e melhorias são bem-vindas.

0
adicionado

Namespaces não têm nada a ver com assemblies - qualquer mapeamento entre um namespace e as classes em uma montagem é puramente devido a uma convenção de nomenclatura (ou coincidência).

0
adicionado
Embora eu concorde, é interessante notar que um projeto do Visual Studio tem um namespace padrão e se você usar o Visual Studio para incorporar um recurso, o nome do recurso de manifesto desse recurso é derivado do namespace padrão e parecerá ser definido pelo próprio assembly se você está sempre usando o Visual Studio para construir o assembly. E vamos encarar isso, isso é bem comum.
adicionado o autor Lisa, fonte

Assemblies não têm necessariamente um namespace raiz. Namespaces e Assemblies são ortogonais.

O que você pode estar procurando, em vez disso, é encontrar um tipo dentro desse assembly e, em seguida, descobrir o que é seu namespace.

Você deve conseguir isso usando o membro GetExportedTypes() e, em seguida, usando a propriedade Namespace de um dos identificadores de tipo retornados.

Novamente, no entanto, não garante que todos os tipos estejam no mesmo namespace (ou mesmo na mesma hierarquia de espaço de nomes).

0
adicionado

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
adicionado

Eu já vi esse dilema muitas vezes quando eu quero carregar um recurso do assembly atual por seu fluxo de recurso de manifesto.

O fato é que, se você incorporar um arquivo como um recurso em seu assembly usando o Visual Studio, seu nome de recurso de manifesto será derivado do namespace padrão do assembly, conforme definido no projeto do Visual Studio.

A melhor solução que obtive (para evitar codificar o namespace padrão como uma string em algum lugar) é simplesmente garantir que seu código de carregamento de recursos esteja sempre acontecendo dentro de uma classe que também esteja no namespace padrão e depois na abordagem genérica seguinte. pode ser usado.

Este exemplo está carregando um esquema incorporado.

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
adicionado
Tive problemas com a resolução de recursos incorporados quando o nome do assembly e o "namespace raiz" do meu projeto não correspondiam. Obrigado pela postagem útil
adicionado o autor Ivaylo Slavov, fonte
Você não pode criar uma classe sem um namespace e usar typeof (DefaultNamespaceHelper) .Namespace?
adicionado o autor drake7707, fonte
Este código realmente funciona. Obrigado!
adicionado o autor Roboblob, fonte
GetType(frm).Namespace

frm is the startup Form

0
adicionado
E se o formulário de inicialização não estiver no namespace raiz?
adicionado o autor Patrick Hofman, fonte

Acabei de criar uma classe interna vazia chamada Root e colocá-lo na raiz do projeto (supondo que este seja o seu namespace raiz). Então eu uso isso em todos os lugares que eu preciso do namespace da raiz:

typeof(Root).Namespace;

Claro que acabo com um arquivo não utilizado, mas está limpo.

0
adicionado
Útil quando precisa disso na mesma montagem, mas não quer codificá-lo.
adicionado o autor CSharper, fonte

Eu uso typeof (App) .Namespace no meu aplicativo WPF. A classe App é obrigatória para qualquer aplicativo wpf e está localizada na raiz.

0
adicionado

Adicionando a todas as outras respostas aqui, espero que sem repetir informações, aqui está como eu resolvi isso usando o Linq. Minha situação é semelhante à resposta de Lisa.

Minha solução vem com as seguintes advertências:

  • Você está usando o Visual Studio e tem um namespace raiz definido para o seu projeto, que eu assumo é o que você está pedindo desde que você use o termo "namespace raiz"
  • Você não está incorporando tipos de interoperabilidade de assemblies referenciados
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
adicionado

Aqui, como uma maneira simples de obter o namespace raiz para um projeto de site.

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

Isso simplesmente verifica todos os assemblies carregados para o tipo "MyProject" e retorna o namespace raiz para esse tipo. Isso é útil para o registro quando você tem vários projetos da Web em uma única solução compartilhando um sistema de log. Espero que isso ajude alguém.

0
adicionado