简体   繁体   English

点源文件中的PowerShell点源 - 导入类

[英]PowerShell dot source within a dot sourced file - import classes

My project is structured like this: 我的项目结构如下:

MyScript.ps1
classes\
    Car.ps1
    Tesla.ps1

Car.ps1 is the base class of Tesla.ps1. Car.ps1是Tesla.ps1的基类。 I attempt to define Tesla like this in Tesla.ps1: 我试图在Tesla.ps1中定义这样的特斯拉:

. "$PSScriptRoot\Car.ps1"

class Tesla : Car
{
}

MyScript.ps1 needs to use the Tesla class, but shouldn't need to know that it inherits from Car. MyScript.ps1需要使用Tesla类,但不需要知道它继承自Car。

. "$PSScriptRoot\classes\Tesla.ps1"

$tesla = [Tesla]::new()

Dot sourcing to classes\\Tesla.ps1 works fine, but this error is thrown from the Tesla file: 点源到classes\\Tesla.ps1工作正常,但这个错误是从特斯拉文件抛出的:

Unable to find type [Car] 找不到类型[Car]

If I import all the files in the correct order in MyScript.ps1, it works fine. 如果我在MyScript.ps1中以正确的顺序导入所有文件,它可以正常工作。 Example: 例:

. "$PSScriptRoot\classes\Car.ps1"
. "$PSScriptRoot\classes\Tesla.ps1"

$tesla = [Tesla]::new()

This is cumbersome, especially as the complexity grows. 这很麻烦,特别是随着复杂性的增加。 Am I dot sourcing incorrectly? 我的点源不正确吗? Is there a better way to import a custom PowerShell class using a relative path that isn't in the PSModulePath? 是否有更好的方法使用不在PSModulePath中的相对路径导入自定义PowerShell类?

PetSerAl , as countless times before, has provided the crucial pointers in a terse comment on the question: PetSerAl ,无数次,在这个问题的简短评论中提供了关键指针:

Due to your use of classes , you must use modules and import them with using module statements in order to use them. 由于您使用了 ,您必须使用模块using module语句导入它们才能使用它们。

Unfortunately, as of this writing, using module is still not mentioned in Get-Help about_Modules ). 不幸的是,在撰写本文时, Get-Help about_Modules仍未提及using module

Specifically, in order to reference a type (class) in a class definition, that type must be known to PowerShell at parse time . 具体来说, 为了引用class定义中的类型(类),PowerShell必须在分析时知道该类型

In your example, in order to derive Tesla from class Car , type Car must be known to PowerShell when the script is parsed , before execution begins - that's why it is too late to try to import Car by dot-sourcing its containing script ( . "$PSScriptRoot\\Car.ps1" ) 在您的示例中,为了从类Car派生Tesla 解析脚本时, 执行开始之前必须知道PowerShell类型为Car ,这就是为什么现在通过点源其包含脚本来导入Car 为时已晚. "$PSScriptRoot\\Car.ps1"

PowerShell knows about referenced types at parse time in one of two ways: PowerShell以两种方式之一了解解析时的引用类型:

  • If the type is already loaded into the current PowerShell session 如果该类型已加载到当前的PowerShell会话中

  • Via a using module statement that references a module in which the type (class) is defined (note that there's also a using assembly statement for loading types from DLLs, and using namespace to enable referring to types by their mere names). 通过using module语句引用其中定义了类型(类)的模块(请注意,还有一个using assembly语句用于从DLL加载类型,并using namespace来启用类型名称引用类型)。

    • Note that the related Import-Module cmdlet does not work in this case, because it executes at runtime . 请注意,相关Import-Module cmdlet 不会在这种情况下工作,因为它执行在运行时

Therefore, as PetSerAl suggests: 因此,正如PetSerAl建议:

  • Store your classes in module files (stand-alone *.psm1 files in the simplest case) 将类存储在模块文件中 (最简单的情况是独立的*.psm1文件)

  • Then use using module to have the Tesla module import the Car module and the MyScript.ps1 script import the Tesla module, using paths that are relative to the enclosing script / module's location . 然后使用using moduleTesla模块导入Car模块, MyScript.ps1脚本使用相对于封闭脚本/模块位置的路径导入Tesla模块。

    • Caveat : As of PowerShell Core 6.1.0-preview.4, there is a bug that requires that you use \\ as the path separator in relative paths with using module , even on Unix-like platforms, where you'd normally use / . 警告 :从PowerShell Core 6.1.0-preview.4开始,有一个错误需要你使用\\作为using module相对路径中的路径分隔符,即使在类似Unix的平台上,你通常使用/
MyScript.ps1
classes\
    Car.psm1    # Note the .psm1 extension
    Tesla.psm1  # Ditto

Car.psm1 : Car.psm1

class Car {}

Tesla.psm1 : Tesla.psm1

using module .\Car.psm1

class Tesla : Car {}

MyScript.ps1 : MyScript.ps1

using module .\classes\Tesla.psm1

$tesla = [Tesla]::new()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM