В моей архитектуре плагина я в настоящее время передаю имя плагина (строку), имя метода (строку) и параметры (массив объектов) в службу моего плагина, чтобы выполнить указанный метод и вернуть результат (типа T).
Метод выполнения службы плагина можно увидеть ниже:
public TResult Execute<TResult>(string pluginName, string operation, params object[] input) {
MethodInfo method = null;
TResult result = default(TResult);
var plugin = _plugins.Enabled().FirstOrDefault(x => x.GetType().Name.Equals(pluginName, StringComparison.InvariantCultureIgnoreCase));
if (plugin != null) {
method = plugin.GetType().GetMethods().FirstOrDefault(x => x.Name == operation);
if (method != null) {
result = (TResult)method.Invoke(plugin, input);
}
}
return result;
}
Пример использования:
var url = AppHelper.PluginService.Execute<string>(
"ImagePlugin",
"GetImageUrl",
new object[] { image, size });
Я бы предпочел вместо этого передать анонимный тип (поскольку я думаю, что это более читабельно), т.е.
var url = AppHelper.PluginService.Execute<string>(
"ImagePlugin",
"GetImageUrl",
new { image = image, targetSize = size });
Как мне изменить свой метод Execute, чтобы сопоставить свойства анонимного типа с параметрами метода моего плагина?
Я рассматривал возможность использования нового динамического типа в .net 4.0, но я предпочитаю определять свои параметры в методе плагина, а не принимать один динамический объект.
Спасибо Бен
[Обновлять]
После просмотра исходного кода ASP.NET MVC кажется достаточно простым вытащить анонимный тип в словарь объектов, например. RouteValueDictionary. С помощью отражения выражение linq создается динамически. Несмотря на то, что это хорошая реализация, мне на самом деле не нужна была вся эта дополнительная сложность.
Согласно приведенному ниже комментарию, я могу добиться удобочитаемости, просто указав свои параметры в строке (нет необходимости в объявлении массива объектов):
var url = AppHelper.PluginService.Execute<string>("ImagePlugin", "GetImageUrl", image, size);
params
, вы можете использоватьimage, size
вместоnew object[] { image, size }
. Это сделало бы его более читабельным, а посколькуInvoke
методы принимают массив объектов, я бы оставил подпись метода как есть. - person Necros   schedule 09.08.2010