it-swarm.it

Ottenere tutti i tipi in uno spazio dei nomi tramite la riflessione

Come si ottengono tutte le classi in uno spazio dei nomi tramite la riflessione in C #?

245
Chethan

Il codice seguente stampa i nomi delle classi nel namespace definito nell'assembly corrente.
Come altri ragazzi hanno sottolineato, uno spazio dei nomi può essere sparso tra i diversi moduli, quindi è necessario prima ottenere un elenco di assiemi.

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));
297
aku

Come dice FlySwat, puoi avere lo stesso spazio dei nomi che si estende in più assiemi (ad esempio System.Collections.Generic). Dovrai caricare tutti quegli assembly se non sono già stati caricati. Quindi per una risposta completa:

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

Questo dovrebbe funzionare a meno che tu non voglia classi di altri domini. Per ottenere un elenco di tutti i domini, segui questo link.

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: il codice sopra mostra cosa sta succedendo. Se lo si implementasse, è possibile utilizzare una versione semplificata:

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);
}
22
Ryan Farley

Per uno specifico Assembly, NameSpace e 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: il progetto deve fare riferimento all'Assemblea

15
John Peters

Ecco una correzione per gli errori LoaderException che è probabile trovare se uno dei tipi sublass un tipo in un altro assieme:

// 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);
}

Ciò dovrebbe aiutare con i tipi di caricamento definiti in altri assiemi.

Spero che sia d'aiuto!

12
tsimon

Non sarai in grado di ottenere tutti i tipi in uno spazio dei nomi, perché uno spazio dei nomi può collegare più assembly, ma puoi ottenere tutte le classi in un assembly e verificare se appartengono a quello spazio dei nomi.

Assembly.GetTypes() funziona sull'assembly locale, oppure puoi prima caricare un assembly, quindi chiamare GetTypes() su di esso.

9
FlySwat

Proprio come la risposta di @aku, ma usando i metodi di estensione:

string @namespace = "...";

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

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

Ottieni tutte le classi per parte del nome dello spazio dei nomi in una sola riga:

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

Gli spazi dei nomi sono in realtà piuttosto passivi nella progettazione del runtime e servono principalmente come strumenti organizzativi. Il nome completo di un tipo in .NET è costituito dallo spazio dei nomi e da Class/Enum/Etc. combinato. Se desideri solo passare attraverso un determinato assieme, esegui semplicemente il ciclo tra i tipi restituiti dall'Assemblea . GetExportedTypes () verifica il valore del tipo . Namespace . Se si stesse tentando di esaminare tutti gli assembly caricati nell'AppDomain corrente, ciò implica l'utilizzo di AppDomain.CurrentDomain . 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

Abbastanza semplice

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