it-swarm-pt.tech

Obtendo todos os tipos em um namespace por meio da reflexão

Como você recebe todas as classes em um namespace através da reflexão em c #?

243
Chethan

O código a seguir imprime nomes de classes em namespace especificado definido no Assembly atual.
Como outros caras apontaram, um namespace pode ser espalhado entre diferentes módulos, então você precisa obter uma lista de assemblies primeiro.

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

Como o FlySwat diz, você pode ter o mesmo namespace abrangendo várias montagens (por exemplo, System.Collections.Generic). Você terá que carregar todos esses conjuntos se eles ainda não estiverem carregados. Então, para uma resposta completa:

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

Isso deve funcionar a menos que você queira classes de outros domínios. Para obter uma lista de todos os domínios, siga este 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: O código acima ilustra o que está acontecendo. Se você fosse implementá-lo, uma versão simplificada pode ser usada:

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 um assembly específico, 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: O projeto deve referenciar a montagem

15
John Peters

Aqui está uma correção para erros de LoaderException que você provavelmente encontrará se um dos tipos sublasses um tipo em outro Assembly:

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

Isso deve ajudar nos tipos de carregamento definidos em outros conjuntos.

Espero que ajude!

12
tsimon

Você não poderá obter todos os tipos em um namespace, porque um namespace pode unir vários assemblies, mas você pode obter todas as classes em um Assembly e verificar se elas pertencem a esse namespace.

Assembly.GetTypes() funciona no Assembly local, ou você pode carregar um Assembly primeiro e depois chamar GetTypes() nele.

9
FlySwat

Apenas como resposta @aku, mas usando métodos de extensão:

string @namespace = "...";

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

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

Obtenha todas as classes por parte do nome do namespace em apenas uma linha:

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

Os namespaces são, na verdade, bastante passivos no design do tempo de execução e servem principalmente como ferramentas organizacionais. O nome completo de um tipo no .NET consiste no espaço para nome e classe/Enum/Etc. combinado. Se você deseja apenas passar por um Assembly específico, você simplesmente passará pelos tipos retornados pelo Assembly . GetExportedTypes () verificando o valor do tipo . Namespace . Se você estivesse tentando percorrer todos os assemblies carregados no AppDomain atual, isso envolveria o uso de 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

Bem simples

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