Reputation: 13
I'm trying to access all the user declared classes in my project. My goal is calling functions of the classes that I access. I have researched this for 2-3 days, but I couldn't find any solutions.
I have tried to get types from assembly but it gave me so complicated results. Here is what I tried:
Assembly assembly = AppDomain.CurrentDomain.GetAssemblies();
Type[] types = assembly.GetTypes();
int i;
for ( i = 0 ; i < types.Length ; i++ )
{
Console.WriteLine( types[ i ].Name );
}
Quick Example - If any other programmer that works on the project creates a class called "Hello", I need to get that class and call the required function inside of it.
I'm stuck with the "getting user/programmer declared classes" part, any help is great.
Update: Thanks to everyone for helping me out. I managed the solve this problem by creating a custom attribute just like how @Ghost4Man suggests. My new code looks like this:
public void Test()
{
foreach ( Assembly a in AppDomain.CurrentDomain.GetAssemblies() )
{
Type[] array = a.GetTypes();
for ( int i = 0 ; i < array.Length ; i++ )
{
Type t = array[ i ];
DConsoleRequired dConsoleRequired = ( DConsoleRequired )
t.GetCustomAttributes( typeof( DConsoleRequired ) , false )[ 0 ];
if ( dConsoleRequired != null )
{
Debug.Log( t.Name );
}
}
}
}
Update 2 : Updated code
public void Test2()
{
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
Type[] types = new Type[ assemblies.Length ];
int i;
for ( i = 0 ; i < assemblies.Length ; i++ )
{
types = assemblies[ i ].GetTypes();
for ( int j = 0 ; j < types.Length ; j++ )
{
var type = types[ j ];
if ( ConsoleRequiredAttribute.IsDefined( type , typeof( ConsoleRequiredAttribute ) ) )
{
Debug.Log( type.Name );
}
}
}
}
Upvotes: 0
Views: 428
Reputation: 391
I wrote a small Console application that addresses your need. You can load assembly dynamically and then inspect it's members.
class Program
{
static void Main(string[] args)
{
var assembly = Assembly.LoadFrom("SomeLibrary.dll");
var types = assembly.GetTypes();
foreach (var type in types)
{
Console.WriteLine($"Type name: {type}");
var functions = type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
foreach (var function in functions)
{
Console.WriteLine($"Function name: {function.Name}");
var instance = Activator.CreateInstance(type, null, null);
var response = function.Invoke(instance, new[] { "Hello from dynamically loaded assembly" });
Console.WriteLine($"Function response: {response}");
}
}
Console.ReadLine();
}
}
It assumes you have all functions that take in one string parameter.
Upvotes: 1
Reputation: 1072
You can annotate the classes with a custom attribute and then filter the types in the assembly by checking if GetCustomAttribute
returns null:
using System.Reflection;
[AttributeUsage(AttributeTargets.Class)]
class HelloAttribute : Attribute { }
[Hello]
class Hello1 { }
[Hello]
class Hello2 { }
and then:
if (types[i].GetCustomAttribute<HelloAttribute>() != null)
{
// do something with the class
}
Or check if the class implements a specific interface:
if (typeof(IHello).IsAssignableFrom(types[i]))
{
// do something with the class
}
Upvotes: 1