Comment obtenir toutes les classes d'un espace de noms par réflexion en C #?
Le code suivant imprime les noms des classes dans la variable namespace
définie dans l’Assemblée actuelle.
Comme l'ont souligné d'autres personnes, un espace de noms peut être dispersé entre différents modules. Vous devez donc d'abord obtenir une liste des assemblys.
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));
Comme le dit FlySwat, vous pouvez avoir le même espace de noms couvrant plusieurs assemblys (par exemple, System.Collections.Generic
). Vous devrez charger tous ces assemblys s'ils ne sont pas déjà chargés. Donc pour une réponse complète:
AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(t => t.GetTypes())
.Where(t => t.IsClass && t.Namespace == @namespace)
Cela devrait fonctionner sauf si vous voulez des classes d'autres domaines. Pour obtenir la liste de tous les domaines, suivez ce lien.
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: Le code ci-dessus illustre ce qui se passe. Si vous deviez l'implémenter, une version simplifiée peut être utilisée:
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);
}
Pour un assembly spécifique, NameSpace et 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();
Remarque: le projet doit référencer l’Assemblée.
Voici un correctif pour les erreurs LoaderException que vous trouverez probablement si l'un des types sous-classe un type dans un autre 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);
}
Cela devrait aider avec les types de chargement définis dans d'autres assemblys.
J'espère que ça t'as aidé!
Vous ne pourrez pas obtenir tous les types dans un espace-noms, car un espace-noms peut relier plusieurs assemblys, mais vous pouvez obtenir toutes les classes dans un assemblage et vérifier s'ils appartiennent à cet espace-noms.
Assembly.GetTypes()
fonctionne sur l'assemblage local ou vous pouvez d'abord charger un assemblage, puis appeler GetTypes()
.
Tout comme @aku answer, mais en utilisant des méthodes d'extension:
string @namespace = "...";
var types = Assembly.GetExecutingAssembly().GetTypes()
.Where(t => t.IsClass && t.Namespace == @namespace)
.ToList();
types.ForEach(t => Console.WriteLine(t.Name));
Obtenez toutes les classes par partie du nom d'espace de nom dans une seule ligne:
var allClasses = Assembly.GetExecutingAssembly().GetTypes().Where(a => a.IsClass && a.Namespace != null && a.Namespace.Contains(@"..your namespace...")).ToList();
Les espaces de noms sont en réalité plutôt passifs dans la conception du moteur d'exécution et servent principalement d'outils d'organisation. Le nom complet d'un type dans .NET est constitué de l'espace de noms et de la classe/énumération/etc. combiné. Si vous souhaitez uniquement parcourir un assemblage spécifique, il vous suffit de parcourir les types renvoyés par Assembly . GetExportedTypes () en vérifiant la valeur du type . Namespace . Si vous tentiez de parcourir tous les assemblys chargés dans le AppDomain actuel, vous utiliseriez AppDomain.CurrentDomain . GetAssemblies ()
//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
Assez facile
Type[] types = Assembly.Load(new AssemblyName("mynamespace.folder")).GetTypes();
foreach (var item in types)
{
}