如何在通过 Add-Type 定义的 Powershell 中使用接口? [英] How to use interfaces in Powershell defined via Add-Type?
问题描述
我开发了一个 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 class
和 enum
定义在之前执行开始和任何类型被解析在此类定义中引用必须是:
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
已经有效,但前提是引用的类型是他们自己 PowerShellclass
/enum
定义.
using module
already works, but only if the referenced types are themselves PowerShellclass
/enum
definitions.
目前,类型从 assemblies 加载 - 无论是通过包含使用 using module
或 using 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 问题:
- 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 withAdd-Type
), that works too, because such types invariably become available session-globally, but it is conceptually cleaner to useNestedModules
, because it dot-sources scripts in the enclosing module's scope
这篇关于如何在通过 Add-Type 定义的 Powershell 中使用接口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- #3461 (
- See the following GitHub issues: