Pergunta

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

Foi útil?

Solução

Não é possível. Nada especifica um namespace "Root". O namespace padrão nas opções é uma coisa visual studio, não é uma coisa .net

Outras dicas

Eu vim através deste dilema muitas vezes quando eu quero carregar um recurso do conjunto atual de seu fluxo de recurso de manifesto.

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

A melhor solução que eu vim acima com (para evitar codificar o namespace padrão como um lugar string) é garantir simplesmente o seu código de carregamento de recursos está sempre acontecendo de dentro de uma classe que é também no namespace padrão e, em seguida, o seguinte perto pode ser usado abordagem -generic.

Este exemplo é carregar 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);

Veja também: Como chegar Namespace de uma Assembléia

Edit: Também notei uma resposta muito detalhada à pergunta que eu estou respondendo a http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/3a469f5d-8f55-4b25-ac25-4778f260bb7e

Outra edição no caso de pessoas com a mesma pergunta vêm à procura: Excelente idéia para resolver a questão de carregamento de recursos aqui: Como obter o namespace padrão do csproj projeto (vS 2008)

Pode haver qualquer número de namespaces em uma determinada montagem, e nada os obriga a todos início de uma raiz comum. O melhor que você poderia fazer seria para refletir sobre todos os tipos em uma montagem e construir uma lista de namespaces exclusivos nele contidas.

Assembléias não têm necessariamente um espaço de nomes raiz. Namespaces e Assembléias são ortogonais.

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

Você deve ser capaz de fazer isso usando os GetExportedTypes () membro e, em seguida, usando a propriedade Namespace de uma das alças tipo retornado.

Novamente, porém, nenhuma garantia de todos os tipos estão no mesmo namespace (ou mesmo na mesma hierarquia namespace).

Acabei de criar uma classe interna vazia chamada raiz e colocá-lo na raiz do projeto (assumindo que este é o seu namespace root). Então eu uso isso em todo lugar que eu preciso o namespace root:

typeof(Root).Namespace;

Claro que eu acabar com um arquivo não utilizado, mas é limpo.

GetType(frm).Namespace

frm é o formulário de inicialização

Get Tipos dá-lhe uma lista de Digite objetos definidos na assembléia. Esse objeto tem uma propriedade namespace. Lembre-se que uma assembleia pode ter vários namespaces.

nomes têm nada a ver com conjuntos - qualquer mapeamento entre um espaço de nomes e as classes de uma montagem é puramente devido a uma convenção de nomenclatura (ou coincidência)

.

Há na verdade é uma forma indireta para obtê-lo, enumerando os nomes dos recursos de manifesto do assembly. O nome que deseja extremidades com a parte dela que você sabe.

Em vez de repetir o código aqui, consulte get padrão namespace nome para Assembly.GetManifestResourceStream () método

Eu uso typeof(App).Namespace no meu aplicativo WPF. classe App é obrigatório para qualquer aplicação WPF e está localizado na raiz.

A pergunta que eu tinha que me desembarcou aqui foi: "Se eu chamar métodos código da biblioteca N profundo e quer que o namespace do projeto - por exemplo, o aplicativo MVC que está realmente funcionando - como faço para que"

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

    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 isso está fazendo está recebendo o stacktrace, descendo os métodos de mais recentemente chamados a raiz, e filtragem para o Sistema. Uma vez que encontra uma chamada de sistema ele sabe que foi longe demais, e retorna o namespace imediatamente acima dele. Se você estiver executando um teste de unidade, um MVC App, ou um serviço, o contentor do sistema vai estar sentado 1 nível mais profundo do que o namespace raiz do seu projeto, então voila.

Em alguns cenários onde o código do sistema é um intermediário (como System.Task) ao longo do traço isso vai voltar a resposta errada. Meu objetivo era tomar por exemplo um código de inicialização e deixá-lo facilmente encontrar uma classe ou controlador ou o que quer na raiz Namespace, mesmo se o código fazendo o trabalho fica em uma biblioteca. Esta realiza essa tarefa.

Tenho certeza de que pode ser melhorado - Tenho certeza que desta forma hacky de fazer as coisas pode ser melhorado em muitos aspectos, e as melhorias são bem-vindas

.

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

A minha solução vem com as seguintes ressalvas:

  • Você está usando o Visual Studio e ter um Namespace de raiz definido para o seu projeto, que eu suponho que é o que você está pedindo desde que você use o termo "namespace root"
  • Você não está embutindo 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
        )
)

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

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

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top