.net - what - ¿Cómo se obtiene el espacio de nombres raíz de un ensamblaje?
what can be done with reflection in c# (13)
Dada una instancia de System.Reflection.Assembly
.
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.
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 ya que utiliza el término "espacio de nombres raíz"
- No está incorporando tipos de interoperabilidad de ensamblados a los que se 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
)
)
Aquí, como una forma bastante simple de obtener el espacio de nombres raíz para un proyecto de sitio web.
'''''' <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 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.
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.
En lugar de repetir el código aquí, consulte obtener el nombre del espacio de nombres predeterminado para el método Assembly.GetManifestResourceStream ()
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
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.
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).
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).
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);
Vea también: ¿Cómo obtener el Espacio de nombres de una Asamblea?
Editar: También noté una respuesta muy detallada a la pregunta que estoy respondiendo en http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/3a469f5d-8f55-4b25-ac25-4778f260bb7e
Otra edición en caso de que vengan personas con la misma pregunta: Excelente idea para resolver la pregunta de carga de recursos aquí: Cómo obtener el espacio de nombre predeterminado del proyecto csproj (VS 2008)
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.
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.
Obtener tipos le da una lista de objetos Type definidos en el conjunto. Ese objeto tiene una propiedad de espacio de nombres. Recuerde que un ensamblaje puede tener múltiples espacios de nombres.
GetType(frm).Namespace
frm
es el formulario de inicio