C#: List All Classes in Assembly
Use Assembly.GetTypes
. For example:
Assembly mscorlib = typeof(string).Assembly;
foreach (Type type in mscorlib.GetTypes())
{
Console.WriteLine(type.FullName);
}
List of classes in an assembly C#
Here's a little class I whipped up some weeks back when I was bored, this does what you're asking of - if I understand the question correctly.
Your applications must implement IPlugin, and must be dropped in a "Plugins" folder in the executing directory.
public interface IPlugin
{
void Initialize();
}
public class PluginLoader
{
public List<IPlugin> LoadPlugins()
{
List<IPlugin> plugins = new List<IPlugin>();
IEnumerable<string> files = Directory.EnumerateFiles(Path.Combine(Directory.GetCurrentDirectory(), "Plugins"),
"*.dll",
SearchOption.TopDirectoryOnly);
foreach (var dllFile in files)
{
Assembly loaded = Assembly.LoadFile(dllFile);
IEnumerable<Type> reflectedType =
loaded.GetExportedTypes().Where(p => p.IsClass && p.GetInterface(nameof(IPlugin)) != null);
plugins.AddRange(reflectedType.Select(p => (IPlugin) Activator.CreateInstance(p)));
}
return plugins;
}
}
Following from Paul's recommendation in the comments, here's a variation using MEF, referencing the System.ComponentModel.Composition
namespace.
namespace ConsoleApplication18
{
using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.IO;
using System.Linq;
public interface IPlugin
{
void Initialize();
}
class Program
{
private static CompositionContainer _container;
static void Main(string[] args)
{
AggregateCatalog catalog = new AggregateCatalog();
catalog.Catalogs.Add(new DirectoryCatalog(Path.Combine(Directory.GetCurrentDirectory(), "Plugins")));
_container = new CompositionContainer(catalog);
IPlugin plugin = null;
try
{
_container.ComposeParts();
// GetExports<T> returns an IEnumerable<Lazy<T>>, and so Value must be called when you want an instance of the object type.
plugin = _container.GetExports<IPlugin>().ToArray()[0].Value;
}
catch (CompositionException compositionException)
{
Console.WriteLine(compositionException.ToString());
}
plugin.Initialize();
Console.ReadKey();
}
}
}
and the DLL file - also referencing the System.ComponentModel.Composition
namespace to set the ExportAttribute
namespace FirstPlugin
{
using System.ComponentModel.Composition;
[Export(typeof(IPlugin))]
public class NamePlugin : IPlugin
{
public void Initialize() { }
}
}
How to find all classes in an assembly that are an instance of a generic abstract class and implement a certain interface
Your problem is actually quite complex to grasp.
The problem is that your class is derived from a generic class, whose generic argument implements the IHttpHandler.
You need to get the inherited (base) type (because you inherit from it).
That's a generic type, so you need to check if it's a generic type.
If it es, you need to get the generic type (GetGenericTypeDefinition).
Then you need to check if the generic type is of type HandlerMiddleware<>
Then you need to get the argument from the generic type.
Then you need to check the first generic argument (if it has one).
Then you need to check if that generic argument's type (or it's derivation base) implements the interface in question.
So in your case:
var ls = FindDerivedTypes(t.Assembly, typeof(HandlerMiddleware<>), typeof(IHttpHandler));
System.Console.WriteLine(ls);
public static List<System.Type> FindDerivedTypes(Assembly assembly
, System.Type typeToSearch
,System.Type neededInterface)
{
List<System.Type> ls = new List<System.Type>();
System.Type[] ta = assembly.GetTypes();
int l = ta.Length;
for (int i = 0; i < l; ++i)
{
if (ta[i].BaseType == null)
continue;
if (!ta[i].BaseType.IsGenericType)
continue;
// public class Middleman : IHttpHandler
// public class HelloWorldHandler2 : HandlerMiddleware<Middleman>
// public class HelloWorldHandler : HandlerMiddleware<HelloWorldHandler>, IHttpHandler
var gt = ta[i].BaseType.GetGenericTypeDefinition();
if (gt == null)
continue;
if (!object.ReferenceEquals(gt, typeToSearch))
continue;
Type[] typeParameters = ta[i].BaseType.GetGenericArguments();
if (typeParameters == null || typeParameters.Length < 1)
continue;
if(neededInterface.IsAssignableFrom(typeParameters[0]))
ls.Add(ta[i]);
} // Next i
return ls;
} // End Function FindDerivedTypes
And that's how you get that list.
Create a list of all classes in namespace using reflection and cast to their real type
SOLVED: The issue was I had internal
constructors and the System.Activator
couldn't create an instance of the class.
Getting All Classe names in a project
The two previous posters are correct. However, if you wanted a list of all referenced assemblies and their types, you could do:
var referencedAssemblies = Assembly.GetExecutingAssembly().GetReferencedAssemblies();
var referencedTypes = referencedAssemblies.SelectMany(x => Assembly.Load(x.FullName).GetTypes());
This would give a list of all Types from the core libraries, third-parties etc which are referenced and used, if you are not using an assembly but have it referenced it wouldn't list its types.
It isn't greatly useful as it lists thousands of types from System and System.Core etc, but i'm not entirely sure what you're trying to achieve, so it may be a start.
List of classes in an assembly
See the documentation for System.Reflection.Assembly.GetTypes() and
System.Type.GetMembers()
--larsw
How to get all classes in current project using reflection?
Given an instance a
of System.Reflection.Assembly, you can get all types in the assembly using:
var allTypes = a.GetTypes();
This will give you all types, public, internal and private.
If you want only the public types, you can use:
var publicTypes = a.GetExportedTypes();
If you are running this code from within the Assembly itself, you can get the assembly using
var a = Assembly.GetExecutingAssembly();
GetTypes and GetExportedTypes will give you all types (structs, classes, enums, interfaces etc.) so if you want only classes you will have to filter
var classes = a.GetExportedTypes().Where(t => t.IsClass);
C# Get List of All Classes with Specific Attribute Parameter
You can just add this to your query:
where type.GetCustomAttribute<GenericConfigAttribute>().MyEnum == GenericConfigType.Type1
For example:
var type1Types =
from type in Assembly.GetExecutingAssembly().GetTypes()
where type.IsDefined(typeof(GenericConfigAttribute), false)
where type.GetCustomAttribute<GenericConfigAttribute>().MyEnum
== GenericConfigType.Type1
select type;
Or simplified slightly (and safer):
var type1Types =
from type in Assembly.GetExecutingAssembly().GetTypes()
where type.GetCustomAttribute<GenericConfigAttribute>()?.MyEnum
== GenericConfigType.Type1
select type;
And if you need to cope with multiple attributes on the same type, you can do this:
var type1Types =
from type in Assembly.GetExecutingAssembly().GetTypes()
where type.GetCustomAttributes<GenericConfigAttribute>()
.Any(a => a.MyEnum == GenericConfigType.Type1)
select type;
How can I get all classes within a namespace?
You will need to do it "backwards"; list all the types in an assembly and then checking the namespace of each type:
using System.Reflection;
private Type[] GetTypesInNamespace(Assembly assembly, string nameSpace)
{
return
assembly.GetTypes()
.Where(t => String.Equals(t.Namespace, nameSpace, StringComparison.Ordinal))
.ToArray();
}
Example of usage:
Type[] typelist = GetTypesInNamespace(Assembly.GetExecutingAssembly(), "MyNamespace");
for (int i = 0; i < typelist.Length; i++)
{
Console.WriteLine(typelist[i].Name);
}
For anything before .Net 2.0 where Assembly.GetExecutingAssembly()
is not available, you will need a small workaround to get the assembly:
Assembly myAssembly = typeof(<Namespace>.<someClass>).GetTypeInfo().Assembly;
Type[] typelist = GetTypesInNamespace(myAssembly, "<Namespace>");
for (int i = 0; i < typelist.Length; i++)
{
Console.WriteLine(typelist[i].Name);
}
How enumerate all classes with custom class attribute?
Yes, absolutely. Using Reflection:
static IEnumerable<Type> GetTypesWithHelpAttribute(Assembly assembly) {
foreach(Type type in assembly.GetTypes()) {
if (type.GetCustomAttributes(typeof(HelpAttribute), true).Length > 0) {
yield return type;
}
}
}
Related Topics
How to Merge Multiple PDF Files (Generated in Run Time)
How to Access Backing Fields Behind Auto-Implemented Properties
Why Always Close Database Connection
C# Error: Parent Does Not Contain a Constructor That Takes 0 Arguments
Check for Device Change (Add/Remove) Events
"On Exit" for a Console Application
No Concurrentlist<T> in .Net 4.0
How to Get Only Time from Date-Time C#
Using C++ Class Dll in C# Application
How to Use the Paint Event to Draw Shapes at Mouse Coordinates
When Is It Appropriate to Use C# Partial Classes
Adjusting Httpwebrequest Connection Timeout in C#
How to Replace Multiple White Spaces with One White Space
Get the Ip Address of the Remote Host
How to Get a List of Properties with a Given Attribute