我正在使用MEF
导入方法。我将此方法称为获取所有导出的方法:
var methods = container.GetExports<Func<int,int,double>,MyMetadata>("contract name");
注意:有时Func<int,int,double>
会发生变化。例如,它可能包含更多参数:Func<int,int,int,double>
。
当我触发方法时,我知道要传递多少参数。 我的问题是如何动态地将参数传递给导入的方法?
更新:
IEnumerable<Lazy<Func<int,int,double>,MyMetadata>> Plugins;
public IEnumerable RunAllPlugins(int a, int b)
{
//my old approach
foreach (var p in Plugins)
{
dynamic a = p;
var b = a.Value.Invoke(a,b); //here I want to pass parameters dynamically
}
//this is new approach which is answer
//now I can pass parameters like array of objects
foreach(var lazyMethod in Plugins)
{
Delegate d=lazyMethod.Value;
object[] numbers=new object[]{1,2};
var result=d.DynamicInvoke(numbers);
}
return null;
}
答案 0 :(得分:2)
一旦你得到Func<>
得到它的类型:
Type type=someFunction.GetType();
现在获取Invoke
成员:
var methodInfo=type.GetMember("Invoke");
这是执行委托时实际调用的方法。您可以在methodInfo上调用GetParameters
以查找它需要多少参数。
如果您已经知道要添加多少参数及其类型,那么事情就更容易了。您只需分配给代理人并致电DynamicInvoke
:
Delegate d=someFuncInstance;
object[] numbers=new object[]{1,2};
var result=d.DynamicInvoke(numbers);
result
将是您需要投射的object
个实例。 someFuncInstance
是Func<>
的一个你从某个地方得到的东西。
所以,对你来说MEF的例子就是这样:
var methods=container.GetExports<Func<int,int,double>,MyMetadata>("contract name");
foreach(var lazyMethod in methods)
{
Delegate d=lazyMethod.Value;
object[] numbers=new object[]{1,2};
var result=d.DynamicInvoke(numbers);
}
答案 1 :(得分:1)
methods
的类型应为IEnumerable<Lazy<Func<int,int,double>>
,所以简单
foreach(var method in methods)
{
method.Value(a,b);
}
应该有效。或者如果您想将其保存以供日后使用:
Func<int,int,double> mySavedDelegate = methods.First();
//...
mySavedDelegate(a,b);
编辑:更好的做法是导出接口并从导入的接口执行所需的方法,而不是直接导出方法。我从来没有做过后者,但从你的问题开始假设它首先是可能的。
答案 2 :(得分:1)
变量函数应该在这里工作。
double Magic(params int[] args)
{
switch(args.Count)
{
case 2: return args[0]+args[1];
case 3: return args[0]+args[1]/args[3];
default: throw new Exception("Not supported");
}
}
然后打电话 魔术(1,2); 要么 魔法(1,2,3);
答案 3 :(得分:0)
我猜你超载了Func<>
界面......
据我所知,您想要获得的是具有特定签名的方法列表:它必须是返回double
并接收2 integers
的方法?那你可能应该返回(!)一个List<>
作为return(!)值吗?
第二:不可能将所有方法都放在特定的Func<>
或Action<>
或其他方面。当然,一些函数会列出输入的不同参数和不同的返回值。对 ?因此,如果(!)您只想处理返回double
并接收2 integers
的函数,那么List<>
将只返回(!)这些类型的方法。请阅读功能签名
new
创建的一样,而我(MEF)会在运行时插入它。所以实际上你并不需要 来获取任何方法的列表。只需确保双方都支持/定义/继承这些方法并使用它们就像在应用程序中定义它们一样