2

此链接:http ://www.codeproject.com/Articles/19911/Dynamically-Invoke-A-Method-Given-Strings-with-Met 清楚地解释了当您将方法名称 + 类型作为字符串变量时如何调用方法.

我正在使用 WatiN 制作 ac# 项目。我使用的所有 WatiN 方法都是相同的形式:

示例: *( ById,.ByClass..; 所以应该连接,但是我无法将其设置为粗体 :s )

  • browser.**TextField**(Find.By **Id**("name")).**TypeText**("my name");
  • browser.**Span**(Find.By **Class**("main_title")).**Click(**);
  • browser.**Link**(Find.By **Id**("mid_link")).**Click(**);

正如你所看到的,这总是由 3 个可变的方法组成。我创建了一个由字符串属性组成的类 webElement:标签、类型、搜索、操作。

在哪里 -> tag = "TextField"; type = "Id", search = "name"; action = "TypeText"

为了动态获取 web 元素,我创建了一个 WebHandler 类,我尝试在其中动态调用正确的方法。

因此,主类拥有所有 webElement 对象的列表,并且可以在给定时间将正确的对象提供给 WebHandler 类。Webhandler 类现在应该动态调用每个元素。我使用与给定 url 相同的调用方法,所以我调用它的代码是:

类WebHandler:

private IE browser = new IE("google.com");

public void method(WebElement webElement)
{
     //Get the findBy dynamically | this works
     WatiN.Core.Constraints.Constraint findBy =
                (WatiN.Core.Constraints.Constraint)InvokeMethod("WatiN.Core.Find, WatiN.Core", "By" + webElement.Type, webElement.Search); //where type = "Id" and search = "name"

     //Get the tag (like textfield, link, span) dynamically | this does not work
     Type aType = Type.GetType("WatiN.Core." + webElement.Tag, "WatiN.Core") //how can I set the element variable to this type? aType element -> Does not work
     aType element = (WatiN.Core.TextField)InvokeMethod("this.browser", webElement.Tag, findBy); //tag = TextField

    element.TypeText("a name"); //same problem as above | so should be invoked
}

问题:

  1. 如何使用他的字符串版本“TextField”作为变量动态调用实例类IE(浏览器)的方法( TextField )?另一种表述方式是:如何通过使用它的字符串版本“浏览器”来获取当前变量(浏览器)?
  2. 如何动态设置变量元素的类型?所以当 webElement.Tag = Textfield 那么类型应该是 WatiN.Core.TexField element = .. (见代码)

自己的考虑:

  1. 我发现的主要问题是您只能从一个类型调用一个方法,而不是从该类型的实例调用。有没有办法做到这一点?
4

3 回答 3

1

这条线

Type aType = Type.GetType("WatiN.Core" + webElement.Tag)

之后没有点Core。它似乎Core是一个命名空间,因此应该与标签名称分开。

于 2012-12-28T16:19:11.087 回答
0

来吧,把它放在 LINQPad 中,但应该或多或少是可移植的:

void Main()
{
    WatiN.Core.Browser theBrowser = new WatiN.Core.IE("google.com");
    Foo(theBrowser, "Id", "gbqfq", "TextField", "TypeText", "Search for this");
}

public void Foo(WatiN.Core.Browser browser, string findTypeBy, string search, string tagName, string elementMethodName, params object[] argsForMethod)
{
    var watinCoreAsm = Assembly.LoadWithPartialName("WatiN.Core");
    if(watinCoreAsm == null) return;

    var watinCoreTypes = watinCoreAsm.GetTypes();
    if(watinCoreTypes == null) return;

    var findType = watinCoreTypes.FirstOrDefault(type => type.Name == "Find");
    if(findType == null) return;

    var constraintInstance = findType.GetMethod("By" + findTypeBy, new Type[]{ typeof(string) }).Invoke(null, new[]{search});
    if(constraintInstance == null) return;

    var browserAccessor = browser.GetType().GetMethod(tagName, new Type[]{ constraintInstance.GetType() });
    if(browserAccessor == null) return;

    var resultElement = browserAccessor.Invoke(browser, new[]{ constraintInstance });
    if(resultElement == null) return;

    var elementMethod = resultElement.GetType().GetMethod(elementMethodName);
    if(elementMethod == null) return;

    elementMethod.Invoke(resultElement, argsForMethod);
}
于 2012-12-28T17:05:47.807 回答
0

这样做的要点是你得到你想要的类型,然后使用反射来获取方法,然后调用给定的方法,传入实例。

所以,像这样:

    Type aType = Type.GetType(string.Format("WatiN.Core.{0}.WatiN.Core", webElement.Tag));
    MethodInfo method = aType.GetMethod("TextField");
    method.Invoke(this.browser, webElement.Tag, findBy);

这里的关键位是:

  1. 获取类型
  2. 获取方法
  3. 使用您想要的实例调用方法

有捷径,我可能没有适合您问题的具体细节,但这应该可以让您接近您想要的。

于 2012-12-28T16:41:21.363 回答