我想知道ASP.NET应用程序中是否有与PHP call_user_func()
等效的函数。我正在寻求从PHP应用程序转换到ASP.NET作为一种自学语言的方法,通过采用专业构建的CMS并尝试用另一种语言重新创建它。
我需要一个类似于此的函数的原因是因为我的PHP CMS的当前结构涉及插件体系结构,并且CMS的特定部分为插件公开自己,然后它将返回的信息作为数组处理。这几乎与Drupal使用的系统相同。
我可能在这个错误的轨道上?
我认为为了澄清,我应该提供一个在我当前系统中如何工作的例子:
<?php
class Test {
function TestMessage() {
// set up array
$arrTest = array("Hello", "World");
// get extra values from all available plugins
$arrExtras = CMS::InvokeHook("HelloTest");
// now contains Hello, World, Foo, Bar
$arrTests = array_merge($arrTest, $arrExtras);
}
}
class CMS {
InvokeHook($function) {
// now contains a couple plugins
$plugins = CMS::GetPlugins();
// empty array of values
$values = array();
foreach($plugins as $plugin) {
// if this plugin has the called method...
if(method_exists($plugin, $function)) {
// call the function and merge in the results
$values[] = call_user_func(array($plugin, $function));
}
}
// return results as an array
return $values;
}
}
class FooTest {
function HelloTest() {
return "Foo";
}
}
class BarTest {
function HelloTest() {
return "Bar";
}
}
?>
注意:InvokeHook()调用被简化,因为我是从内存中写的,但这就是它的要点。
答案 0 :(得分:3)
在.NET中我可能会创建一些事件并处理它们。这是一种方法:
public class CMS
public Event DoSomethingHook(byval sender as Object, byval e as DoSomethingEventArgs)
public function DoSomething()
dim data() as Integer = {}
Dim e as new DoSomethingEventArgs();
e.data = data
RaiseEvent DoSomethingHook(Me, e)
data = e.data
end function
end class
' Let's say Plugin base class contains a reference to CMS
public class CMSPlugin
Inherits Plugin
public sub New()
' Register for a hook
AddHandler CMS.DoSomethingHook, AddressOf DoSomething
end sub
public function DoSomething(byval sender as Object, byval e as DoSomethingEventArgs)
' Do something with e.data
end function
end class
public class DoSomethingEventArgs : Inherits EventArgs
public data() as Integer
end class
答案 1 :(得分:0)
对于.NET开发人员来说,这基本上是一种从给定名称(作为字符串)调用方法的方法。
对OP :(我认为)你必须使用反射。它远没有那么漂亮,而且相当昂贵(IIRC),所以最好不要过度使用。
System.Reflection.MethodInfo method = this.GetType().GetMethod(myMethodName);
// method.Invoke(args, null);
如果您不得不求助于此事,我认为您可能会以“错误”的方式做事。有一种更清洁的模式可以更好地发挥作用。
我制作插件架构的方式是通过全局共享接口*所以插件可以实现“插件”接口*然后我知道会有一个.DoSomething()(等)方法可用。不需要反思=)
*或抽象类......真的,无论什么最合适!