2008-09-18 18 views

Respuesta

34

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

+2

Debajo de la publicación del usuario Lisa en realidad funciona así que esta respuesta está marcada como respuesta, pero sin la razón adecuada. – Roboblob

+6

@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. – Lisa

9

Puede haber cualquier cantidad de espacios de nombres en un ensamblaje dado, y nada requiere que todos comiencen 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.

4

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 ese ensamblado, y luego averiguar cuál es su espacio de nombre.

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

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

1

Get Types le ofrece una lista de Type objetos definidos en el conjunto. Ese objeto tiene una propiedad de espacio de nombres. Recuerde que un ensamblaje puede tener múltiples espacios de nombres.

0

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

+3

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 manifiesto de ese recurso se deriva del espacio de nombres predeterminado y parecerá definido por el propio ensamblaje si siempre está usando Visual Studio para construir el ensamblaje. Y admitámoslo, esto es bastante común. – Lisa

47

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 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 nombres predeterminado como una cadena en algún lugar) es simplemente asegurar que el código de carga de recursos SIEMPRE está ocurriendo dentro de una clase que también está en el espacio de nombres predeterminado y luego enfoque casi genérico puede ser utilizado.

Este ejemplo se 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); 

Consulte también: How to get Namespace of an Assembly?

Editar: También notó una respuesta muy detallada a la pregunta Estoy respondiendo a http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/3a469f5d-8f55-4b25-ac25-4778f260bb7e

Otra edición en casos de personas con la misma pregunta vienen buscando: Excelente idea resolver la cuestión de los recursos de carga aquí: How get the default namespace of project csproj (VS 2008)

+1

Este código realmente funciona. ¡Gracias! – Roboblob

+2

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 –

+0

¿No puedes crear una clase sin un espacio de nombres y usar typeof (DefaultNamespaceHelper) .Namespace? – drake7707

2
GetType(frm).Namespace 

frm es el st artup Form

+0

¿Qué ocurre si el formulario de inicio no está en el espacio de nombres raíz? –

3

acabo de crear una clase interna vacío llamado Raíz y la puso en la raíz del proyecto (suponiendo que esta es su espacio de nombres raíz). Luego utilizo esto en todas partes necesito el espacio de nombres raíz:

typeof(Root).Namespace; 

Claro que terminan con un archivo sin usar, pero está limpio.

+0

Útil cuando se necesita esto en el mismo ensamblaje, pero no se desea codificarlo. – CSharper

0

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

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, ¿cómo lo obtengo?"

Un poco hacky, pero sólo puede tomar un StackTrace y 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; 
    } 

Todo esto está haciendo es conseguir que el StackTrace, corriendo por los métodos de la última llamada a la raíz, y filtrado para el sistema. 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 casos en los que 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 manera de hacer hacky se puede mejorar de muchas maneras, y las mejoras son bienvenidas.

0

Agregando a todas las demás respuestas aquí, con suerte sin repetir la información, así es como lo resolví usando Linq. Mi situación es similar a la respuesta de Lisa.

Mi solución viene con las siguientes salvedades:

  • Estás utilizando Visual Studio y ha definido un espacio de nombres raíz para su proyecto, que supongo que es lo que está pidiendo ya que se utiliza el término " espacio de nombres raíz"
  • no se incrusta tipos de interoperabilidad de ensamblados de 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

aquí como una manera bastante sencilla para obtener el espacio de nombres raíz de un sitio web proje Connecticut.

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

Esto simplemente comprueba todos los ensamblados cargados para el tipo "MiProyecto" y devuelve el espacio de nombres raíz de 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.

Cuestiones relacionadas