¿Cómo se obtiene el espacio de nombres raíz de un ensamblaje?

Dada una instancia de System.Reflection.Assembly .

0
agregado editado
Puntos de vista: 1

13 Respuestas

Imposible. Nada especifica un espacio de nombre "Root". El espacio de nombre predeterminado en las opciones es una cosa visual de estudio, no una cosa de .net

0
agregado
@Roboblob La respuesta de Darren es técnicamente correcta. El mío es meramente útil en el 95% de los casos en que desea saber esto en el contexto de la construcción de un proyecto en VS.
agregado el autor Lisa, fuente
Debajo de la publicación del usuario, Lisa realmente funciona, por lo que esta respuesta se marca como respuesta, pero sin la razón adecuada.
agregado el autor Roboblob, fuente

Puede haber cualquier cantidad de espacios de nombres en un ensamblaje dado, y nada los requiere para comenzar desde una raíz común. Lo mejor que podría hacer sería reflejar todos los tipos en un ensamblado y crear una lista de espacios de nombres únicos contenidos en él.

0
agregado

En realidad, hay una manera indirecta de obtenerlo, enumerando los nombres de los recursos manifiestos de la asamblea. El nombre que quieres termina con la parte que conoces.

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

0
agregado

La pregunta que tuve que me aterrizó aquí fue: "Si llamo al código de la biblioteca N métodos profundos y quiero el espacio de nombres del Proyecto, por ejemplo, la aplicación MVC que se está ejecutando en realidad, ¿cómo puedo obtener eso?"

Un poco raro, pero puedes agarrar un stacktrace y 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;
    }

Todo lo que hace es obtener stacktrace, bajar los métodos desde el más reciente llamado a root y filtrar para System. Una vez que encuentra una llamada al Sistema, sabe que ha ido demasiado lejos, y le devuelve el espacio de nombres inmediatamente encima. Ya sea que esté ejecutando una prueba de unidad, una aplicación de MVC o un servicio, el contenedor del sistema se ubicará 1 nivel más profundo que el espacio de nombres raíz de su proyecto, así que listo.

En algunos escenarios donde el código del sistema es un intermediario (como System.Task) a lo largo del seguimiento, esto arrojará la respuesta incorrecta. Mi objetivo era tomar, por ejemplo, un código de inicio y dejar que encuentre fácilmente una clase o Controlador o lo que sea en el Espacio de nombres raíz, incluso si el código que hace el trabajo se queda en una biblioteca. Esto logra esa tarea.

Estoy seguro de que se puede mejorar: estoy seguro de que esta forma de hacer hacky se puede mejorar de muchas maneras, y las mejoras son bienvenidas.

0
agregado

Los espacios de nombres no tienen nada que ver con los ensamblajes: cualquier asignación entre un espacio de nombres y las clases en un ensamblaje se debe simplemente a una convención de nomenclatura (o coincidencia).

0
agregado
Aunque estoy de acuerdo, vale la pena señalar que un proyecto de Visual Studio tiene un espacio de nombres predeterminado y si usa Visual Studio para incrustar un recurso, el nombre del recurso de manifiesto de ese recurso se deriva del espacio de nombres predeterminado y parecerá que está definido por el ensamblado si Siempre estoy usando Visual Studio para construir el ensamblado. Y admitámoslo, esto es bastante común.
agregado el autor Lisa, fuente

Los ensamblados no tienen necesariamente un espacio de nombres raíz. Los espacios de nombres y ensamblajes son ortogonales.

Lo que puede estar buscando, en su lugar, es encontrar un tipo dentro de esa Asamblea, y luego averiguar cuál es su espacio de nombres.

Debería poder lograr esto utilizando el miembro GetExportedTypes() y luego usando la propiedad Namespace de uno de los identificadores Type recuperados.

Sin embargo, una vez más, no hay garantías de que todos los tipos estén en el mismo espacio de nombres (o incluso en la misma jerarquía del espacio de nombres).

0
agregado

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
agregado

Me he encontrado con este dilema muchas veces cuando quiero cargar un recurso del ensamblado actual por su secuencia de recursos de manifiesto.

El hecho es que si incorpora un archivo como un recurso en su ensamblado utilizando Visual Studio, su nombre de recurso de manifiesto se derivará del espacio de nombres predeterminado del ensamblaje como se define en el proyecto de Visual Studio.

La mejor solución que he encontrado (para evitar codificar el espacio de nombre predeterminado como una cadena en algún lugar) es simplemente asegurar que el código de carga de recursos SIEMPRE está sucediendo desde dentro de una clase que también está en el espacio de nombres predeterminado y luego con el siguiente acercamiento genérico puede ser usado.

Este ejemplo está cargando un esquema incrustado.

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
agregado
Tuve problemas con la resolución de recursos incorporados cuando el nombre del ensamblado y el "espacio de nombres raíz" de mi proyecto no coincidían. Gracias por la útil publicación
agregado el autor Ivaylo Slavov, fuente
¿No puedes crear una clase sin un espacio de nombres y usar typeof (DefaultNamespaceHelper) .Namespace?
agregado el autor drake7707, fuente
Este código realmente funciona. ¡Gracias!
agregado el autor Roboblob, fuente
GetType(frm).Namespace

frm is the startup Form

0
agregado
¿Qué pasa si el formulario de inicio no está en el espacio de nombres raíz?
agregado el autor Patrick Hofman, fuente

Acabo de crear una clase interna vacía llamada Root y ponerla en la raíz del proyecto (suponiendo que este sea su espacio de nombres raíz). Luego uso esto en todas partes Necesito el espacio de nombres raíz:

typeof(Root).Namespace;

Seguro que termino con un archivo sin usar, pero está limpio.

0
agregado
Útil cuando se necesita esto en el mismo ensamblaje, pero no se desea codificarlo.
agregado el autor CSharper, fuente

Uso typeof (App) .Namespace en mi aplicación WPF. La clase de aplicación es obligatoria para cualquier aplicación wpf y está ubicada en la raíz.

0
agregado

Agregando a todas las otras respuestas aquí, con suerte sin repetir la información, aquí es cómo resolví esto usando Linq. Mi situación es similar a la respuesta de Lisa.

Mi solución viene con las siguientes advertencias:

  • Está utilizando Visual Studio y tiene un espacio de nombre raíz definido para su proyecto, que supongo que es lo que está pidiendo porque usa el término "espacio de nombres raíz"
  • No está incorporando tipos de interoperabilidad de ensamblados a los que hace referencia
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
agregado

Aquí, como una forma bastante simple de obtener el espacio de nombres raíz para un proyecto de sitio 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

Esto simplemente verifica todos los ensamblajes cargados para el tipo "MyProject" y devuelve el espacio de nombres raíz para ese tipo. Esto es útil para iniciar sesión cuando tiene múltiples proyectos web en una única solución que comparte un sistema de registro. Espero que esto ayude a alguien.

0
agregado