代码之家  ›  专栏  ›  技术社区  ›  Rohit

在托管环境中查询Ironpython脚本的接口

  •  2
  • Rohit  · 技术社区  · 16 年前

    我正在开发一个用C语言编写的应用程序,它承载Ironpython。我计划的是,用户将编写Python脚本,其中包含实现预定义接口的类。

    类似:

    用C代码定义接口:

    public interface IPlugin
    {
        void DoSomething();
    }
    

    用python代码实现接口。

    class Plugin(IPlugin):
    
          def DoSomething():
              print "Doing stuff."
    

    在我的应用程序中,我加载python脚本并执行那些脚本中的类实现的方法。

    我想知道:如何获得实现Python脚本中指定接口的所有类的句柄?

    例如:如果我要在C中完成整件事情,我会考虑帮助我,我可以直接加载组件,然后执行如下操作:

        Assembly assembly = Assembly.LoadFrom("plugin.dll");
        Type[] types = assembly.GetTypes();
        foreach(Type type in types)
        {
            foreach(Type interfaceType in type.GetInterface())
            {
                if(interfaceType == typeof(IPlugin))
                {
                    // gotcha, invoke interface specific methods
                }
            }
         }
    

    当我处理的不是程序集而是一个Ironpython脚本时,我该怎么做呢?我知道,使用ObjectOperations和ScriptScope,如果我知道类的名称,就可以获得该类的句柄。-- as described here --但我在找更结实的东西。

    4 回复  |  直到 8 年前
        1
  •  3
  •   Alastair McCormack    8 年前

    问题是Ironpython类不是.NET类。python类比c类更具动态性,因此Ironpython类通常是.NET对象。

    当您在Ironpython中对.NET接口进行子类化时, 创建一个新的.NET类,但多个python类实际上共享一个backing.NET类(在Ironpython中,每个.NET类型子类只创建一个.NET类)。

    正确的方法是使用python自省来收集Ironpython类对象,并在需要实例化它们的地方使用工厂函数(可以用作委托-将返回的实例强制转换到接口)。

    例如,您可以尝试在python范围内执行:

    list_of_classes = IPlugin.\_\_subclasses_\_
    
        2
  •  1
  •   Ana Betts    16 年前

    动态语言通常不使用接口,您以非常静态的方式思考:)

    您不必担心它是否与某个预定义的接口匹配,只需调用成员函数并处理抛出的任何异常——无论如何,您都必须处理错误,只需使“不符合我们期望的方法调用”成为一个新的。在目标C中,这称为“非正式议定书”。

        3
  •  1
  •   Srivatsn Narayanan    16 年前

    始终可以通过调用clr.getclrType来获取python类型的backing.net类型。

    getclrmodule(engine)返回clr模块,然后对其调用getclrType方法,并传入使用ObjectOperations获得的python类。这应该会给你一个system.type。之后,像通常那样使用getInterfaces方法。

        4
  •  0
  •   Mitch Denny    16 年前

    根据Ironpython常见问题解答,它不支持将*.py文件编译为可链接到以下对象的程序集:

    http://ironpython.codeplex.com/Wiki/View.aspx?title=FAQ&referringTitle=Home

    但是Paul是正确的,如果您打算使用动态语言来实现这种扩展性,那么您可能希望使它像编辑文件一样简单,而不是必须从运行时了解接口。

    如果要向系统管理员类型公开此扩展性点,您可能需要考虑托管PowerShell。不久前我写了一篇关于如何做到这一点的文章:

    http://notgartner.wordpress.com/2008/02/23/how-to-host-the-powershell-runtime/

    PowerShell很适合这样做,因为它已经在使用Exchange的环境中得到了一些采用。注意-我是一个PowerShell的粉丝,所以带上一粒盐吧:)

    推荐文章