it-swarm-es.tech

Obteniendo todos los tipos en un espacio de nombres a través de la reflexión.

¿Cómo se obtienen todas las clases en un espacio de nombres a través de la reflexión en C #?

243
Chethan

El siguiente código imprime los nombres de las clases en la namespace especificada definida en el ensamblado actual.
Como señalaron otros chicos, un espacio de nombres se puede dispersar entre diferentes módulos, por lo que primero debe obtener una lista de ensamblajes.

string nspace = "...";

var q = from t in Assembly.GetExecutingAssembly().GetTypes()
        where t.IsClass && t.Namespace == nspace
        select t;
q.ToList().ForEach(t => Console.WriteLine(t.Name));
294
aku

Como dice FlySwat, puede tener el mismo espacio de nombres que abarca varios ensamblajes (por ejemplo, System.Collections.Generic). Tendrá que cargar todos esos ensamblajes si aún no están cargados. Así que para una respuesta completa:

AppDomain.CurrentDomain.GetAssemblies()
                       .SelectMany(t => t.GetTypes())
                       .Where(t => t.IsClass && t.Namespace == @namespace)

Esto debería funcionar a menos que quieras clases de otros dominios. Para obtener una lista de todos los dominios, siga este enlace.

69
nawfal
using System.Reflection;
using System.Collections.Generic;
//...

static List<string> GetClasses(string nameSpace)
{
    Assembly asm = Assembly.GetExecutingAssembly();

    List<string> namespacelist = new List<string>();
    List<string> classlist = new List<string>();

    foreach (Type type in asm.GetTypes())
    {
        if (type.Namespace == nameSpace)
            namespacelist.Add(type.Name);
    }

    foreach (string classname in namespacelist)
        classlist.Add(classname);

    return classlist;
}

NB: El código anterior ilustra lo que está pasando. Si lo implementas, puedes usar una versión simplificada:

using System.Linq;
using System.Reflection;
using System.Collections.Generic;
//...

static IEnumerable<string> GetClasses(string nameSpace)
{
    Assembly asm = Assembly.GetExecutingAssembly();
    return asm.GetTypes()
        .Where(type => type.Namespace == nameSpace)
        .Select(type => type.Name);
}
21
Ryan Farley

Para un ensamblado específico, NameSpace y ClassName:

var assemblyName = "Some.Assembly.Name"
var nameSpace = "Some.Namespace.Name";
var className = "ClassNameFilter";

var asm = Assembly.Load(assemblyName);
var classes = asm.GetTypes().Where(p =>
     p.Namespace == nameSpace &&
     p.Name.Contains(className) 
).ToList();

Nota: El proyecto debe hacer referencia a la Asamblea.

15
John Peters

Aquí hay una solución para los errores LoaderException que es probable que encuentre si uno de los tipos sub-clasifica un tipo en otro Ensamblaje:

// Setup event handler to resolve assemblies
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += new ResolveEventHandler(CurrentDomain_ReflectionOnlyAssemblyResolve);

Assembly a = System.Reflection.Assembly.ReflectionOnlyLoadFrom(filename);
a.GetTypes();
// process types here

// method later in the class:
static Assembly CurrentDomain_ReflectionOnlyAssemblyResolve(object sender, ResolveEventArgs args)
{
    return System.Reflection.Assembly.ReflectionOnlyLoad(args.Name);
}

Eso debería ayudar con la carga de tipos definidos en otros ensamblajes.

¡Espero que ayude!

12
Travis

No podrá obtener todos los tipos en un espacio de nombres, ya que un espacio de nombres puede unir varios ensamblajes, pero puede obtener todas las clases en un ensamblaje y verificar si pertenecen a ese espacio de nombres.

Assembly.GetTypes() funciona en la Asamblea local, o puede cargar una Asamblea primero y luego llamar a GetTypes().

9
FlySwat

Al igual que @aku responde, pero usando métodos de extensión:

string @namespace = "...";

var types = Assembly.GetExecutingAssembly().GetTypes()
    .Where(t => t.IsClass && t.Namespace == @namespace)
    .ToList();

types.ForEach(t => Console.WriteLine(t.Name));
5
JoanComasFdz

Obtenga todas las clases por parte del nombre del espacio de nombres en una sola fila:

var allClasses = Assembly.GetExecutingAssembly().GetTypes().Where(a => a.IsClass && a.Namespace != null && a.Namespace.Contains(@"..your namespace...")).ToList();
5
Ivo Stoyanov

Los espacios de nombres son en realidad bastante pasivos en el diseño del tiempo de ejecución y sirven principalmente como herramientas de organización. El nombre completo de un tipo en .NET consiste en el espacio de nombres y Class/Enum/Etc. conjunto. Si solo desea pasar por un Ensamblaje específico, simplemente recorrerá los tipos devueltos por Assembly. GetExportedTypes () verificando el valor de type. Namespace . Si intentara pasar por todos los ensamblados cargados en el dominio de aplicación actual, esto implicaría el uso del dominio de aplicación.Dominio actual. GetAssemblies ()

3
TheXenocide
//a simple combined code snippet 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace MustHaveAttributes
{
  class Program
  {
    static void Main ( string[] args )
    {
      Console.WriteLine ( " START " );

      // what is in the Assembly
      Assembly a = Assembly.Load ( "MustHaveAttributes" );
      Type[] types = a.GetTypes ();
      foreach (Type t in types)
      {

        Console.WriteLine ( "Type is {0}", t );
      }
      Console.WriteLine (
         "{0} types found", types.Length );

      #region Linq
      //#region Action


      //string @namespace = "MustHaveAttributes";

      //var q = from t in Assembly.GetExecutingAssembly ().GetTypes ()
      //        where t.IsClass && t.Namespace == @namespace
      //        select t;
      //q.ToList ().ForEach ( t => Console.WriteLine ( t.Name ) );


      //#endregion Action  
      #endregion

      Console.ReadLine ();
      Console.WriteLine ( " HIT A KEY TO EXIT " );
      Console.WriteLine ( " END " );
    }
  } //eof Program


  class ClassOne
  {

  } //eof class 

  class ClassTwo
  {

  } //eof class


  [System.AttributeUsage ( System.AttributeTargets.Class |
    System.AttributeTargets.Struct, AllowMultiple = true )]
  public class AttributeClass : System.Attribute
  {

    public string MustHaveDescription { get; set; }
    public string MusHaveVersion { get; set; }


    public AttributeClass ( string mustHaveDescription, string mustHaveVersion )
    {
      MustHaveDescription = mustHaveDescription;
      MusHaveVersion = mustHaveVersion;
    }

  } //eof class 

} //eof namespace 
2
Yordan Georgiev

Bastante sencillo

Type[] types = Assembly.Load(new AssemblyName("mynamespace.folder")).GetTypes();
foreach (var item in types)
{
}
2
Antonio Lopes