如何在通过 Add-Type 定义的 Powershell 中使用接口? [英] How to use interfaces in Powershell defined via Add-Type?

查看:111
本文介绍了如何在通过 Add-Type 定义的 Powershell 中使用接口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开发了一个 PowerShell 模块,该模块依赖于 .NET 程序集进行某些操作.
我将这个模块重构为不需要那个程序集,并注意到一些奇怪的行为,这最终阻止了我删除该类:

I developed a PowerShell module that relied on a .NET Assembly for some operations.
I refactored this module to not need that Assembly and noticed some strange behavior, which blocks me from removing the class at last:

Add-Type -TypeDefinition "public interface ICanTalk { string talk(); }" -Language CSharp

class Talker : ICanTalk {
    [string] talk() { return "Well hello there"; }
}

如果您以交互方式运行此命令,它将成功.但是一旦我在 ISE 中或从 psm1 文件中en-bloque"运行它,它就会抛出一个错误,指出它找不到在 Add-Type 调用中定义的接口.

If you run this commands interactively, it will succeed. But as soon as I run it "en-bloque" in ISE or from a psm1 file, it will throw an error, stating it cannot find the interface defined in the Add-Type call.

我可以在 Windows-PowerShell 和 PowerShell Core (6.0.2) 中重现该问题

I can reproduce the problem in both Windows-PowerShell and PowerShell Core (6.0.2)

不同行为的原因是什么,我该如何解决?

What is the reason for the different behaviour and how can I tackle it?

推荐答案

补充你自己的答案:

PowerShell classenum 定义在之前执行开始和任何类型被解析在此类定义中引用必须是:

PowerShell class and enum definitions are parsed before execution begins and any types referenced in such definitions must either be:

  • 加载到当前会话预先.

[仅部分实现自 Windows PowerShell v5.1/PowerShell Core 6.1.0]
通过using module/using assembly语句加载文件顶部.

[only partially implemented as of Windows PowerShell v5.1 / PowerShell Core 6.1.0]
loaded via a using module / using assembly statement at the very top of the file.

  • using module 已经有效,但前提是引用的类型是他们自己 PowerShell class/enum 定义.

  • using module already works, but only if the referenced types are themselves PowerShell class / enum definitions.

目前,类型从 assemblies 加载 - 无论是通过包含使用 using moduleusing assembly 导入的程序集的模块直接加载一个程序集 - 尚未检测到.

Currently, types loaded from assemblies - whether via a module containing assemblies imported with using module or using assembly to directly load an assembly - aren't yet detected.

  • 请参阅以下 GitHub 问题:
    • #3461(使用模块) 和 #2074(使用汇编)
    • #6652 - 一个跟踪所有类相关问题的元问题.立>
    • See the following GitHub issues:
      • #3461 (using module) and #2074 (using assembly)
      • #6652 - a meta issue tracking all class-related issues.

      同时解决方法通过使用模块清单的NestedModules预先通过单独的脚本加载引用类型条目.

      The workaround in the meantime is to load the referenced types via a separate script beforehand, by using the module manifest's NestedModules entry.

      • 注意:ScriptsToProcess 条目也可以使用,但它引用的脚本是在 调用方 中点源(加载到当前范围内),而不是封闭的模块.
        使用来自编译代码的类型(包括带有 Add-Type 的临时编译代码),这也有效,因为这些类型总是在会话全局可用,但它在概念上是使用 NestedModules 更干净,因为它在封闭的 module 范围内点源脚本
      • Note: The ScriptsToProcess entry would work too, but the scripts it references are dot-sourced in (loaded into the current scope of) the caller, not the enclosing module.
        With types from compiled code (including ad hoc-compiled code with Add-Type), that works too, because such types invariably become available session-globally, but it is conceptually cleaner to use NestedModules, because it dot-sources scripts in the enclosing module's scope

      这篇关于如何在通过 Add-Type 定义的 Powershell 中使用接口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆