Выполнить любой метод по строке с параметрами - PullRequest
0 голосов
/ 16 декабря 2011

Я возился с CMS, которую я делаю как личный проект, и я дошел до того, что застрял.

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

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

Пример кода шаблона:

Пока что я правильно проанализировал это, у меня есть имя метода и параметры в виде строк, целых, bools и т. Д.

Менеджер плагинов, который я написал, тоже работает нормально, но у меня проблемы с их соединением.

Скажем, например, это класс плагина:

[Plugin(Name="Test")]
public class TestPlugin
{
    private DateTime _startTime;

    public TestPlugin()
    {
        _startTime = DateTime.Now;
    }

    [TemplateAction]
    public string Test(int number, string testString)
    {
        return "TEST";
    }
}

Мне нужно иметь возможность вызывать Test () из моего разобранного шаблона и передавать любые параметры из шаблона в метод. Я создал System.Delegate из метода, помеченного атрибутом, и добавил выражение в шаблонизатор как часть кэшированного метода для вызова Test ().

Чего я не знаю, так это как передать проанализированные параметры из шаблона в метод. Я попытался создать объект [] и передать его в DynamicInvoke на делегате, но он пожаловался на несоответствие аргумента, поэтому я немного застрял. Я не уверен, что вы можете передать object [] в метод, который имеет (params object [] args) в качестве подписи через выражения.

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

Извините, если неясно, любые вопросы не стесняйтесь задавать.

Любая помощь очень ценится.

Рик.

UPDATE

Хорошо, подумав, и благодаря Д. Стэнли я ​​сделал это.

foreach (var method in type.GetMethods().Where(x => x.GetCustomAttributes(typeof(TemplateActionAttribute), true).Length > 0))
{
    if (method.ReturnType != typeof(string)) continue;

    PluginTemplateActions.Add(method.Name, o => (string)method.Invoke(plugin, o));
}

Пока все работает так, как я хочу, но будет ли это быстрее, чем DynamicInvoke?

1 Ответ

0 голосов
/ 16 декабря 2011

Вы можете использовать отражение:

TestPlugin plugIn = new TestPlugin();
object[] params = null //... set parameters here
MethodInfo mi = typeof(TestPlugin).GetMethod("Test");
mi.invoke(plugIn,params);
...