Получение пользователем объявленных классов с отражением - PullRequest
0 голосов
/ 17 октября 2018

Я пытаюсь получить доступ ко всем объявленным пользователем классам в моем проекте.Моя цель - вызывать функции классов, к которым я обращаюсь.Я исследовал это в течение 2-3 дней, но я не мог найти никаких решений.

Я пытался получить типы из сборки, но это дало мне такие сложные результаты.Вот что я попробовал:

Assembly assembly = AppDomain.CurrentDomain.GetAssemblies();
Type[] types = assembly.GetTypes();

int i;
for ( i = 0 ; i < types.Length ; i++ )
{
    Console.WriteLine( types[ i ].Name );
}

Быстрый пример - Если какой-либо другой программист, работающий над проектом, создает класс с именем «Hello», мне нужно получить этот класс и вызвать внутри него требуемую функцию.

Я застрял в части "получение классов, объявленных пользователем / программистом", любая помощь великолепна.


Обновление: Спасибо всем за помощьиз.Мне удалось решить эту проблему, создав собственный атрибут, аналогичный тому, что предлагает @ Ghost4Man.Мой новый код выглядит так:

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

Обновление 2: Обновленный код

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

Ответы [ 2 ]

0 голосов
/ 17 октября 2018

Я написал небольшое консольное приложение, которое отвечает вашим потребностям.Вы можете загружать сборку динамически и затем проверять ее элементы.

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

Предполагается, что у вас есть все функции, которые принимают один строковый параметр.

0 голосов
/ 17 октября 2018

Вы можете аннотировать классы с помощью пользовательского атрибута, а затем фильтровать типы в сборке, проверяя, возвращает ли GetCustomAttribute ноль:

using System.Reflection;

[AttributeUsage(AttributeTargets.Class)]
class HelloAttribute : Attribute { }

[Hello]
class Hello1 { }

[Hello]
class Hello2 { }

, а затем:

if (types[i].GetCustomAttribute<HelloAttribute>() != null)
{
    // do something with the class
}

Или проверьте, реализует ли класс определенный интерфейс:

if (typeof(IHello).IsAssignableFrom(types[i]))
{
    // do something with the class
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...