Как правильно установить область действия в модуле powershell? - PullRequest
0 голосов
/ 14 мая 2018

Фон

Я бы хотел, чтобы все мои скрипты и модули были основаны на шаблонном скрипте, который заботится о некоторых типичных «домашних делах».

Некоторые из моих модулей взаимозависимы, и поэтому я могу загрузить модуль внутри другого модуля, даже если он временно.

Однако, поскольку код является шаблонным, основные функции инициализации имеют одинаковые имена. На мой взгляд, это не должно быть проблемой, если я правильно оцениваю ситуацию, но оказывается, что это проблема.

Демонстрация проблемы

В демонстрации ниже будет 1 скрипт, который загружает модуль, который, в свою очередь, загружает другой модуль. Каждый модуль имеет код инициализации, который запускается при загрузке модуля.

  • Обновление : обновлен код, чтобы немного лучше продемонстрировать, почему он структурирован таким, какой он есть, хотя ответ уже был принят.

module.level2.psm1

# module.level2.psm1
# list of modules loaded by template code
$script:LoadModule = $null

# module housekeeping code - called from template code
function ModuleSpecificInitCode {
    Write-Host "Level 2 Code"
}

function Level2ModuleFunction {
    Write-Host "This is why I imported Level 2 module"
}

# module housekeeping code - template code
function TemplateInitCode {
    Write-Host "Level 2 Init"
    $LoadModule | % { Import-Module ".\$_.psm1" }
}

TemplateInitCode 
try {
    ModuleSpecificInitCode 
} catch {
# Error handling
}

module.level1.psm1

# module.level1.psm1
# list of modules loaded by template code
$script:LoadModule = "module.level2"

# module housekeeping code - called from template code
function ModuleSpecificInitCode {
    Write-Host "Level 1 Code"
}

function Level1ModuleFunction {
    Write-Host "This is why I imported Level 1 module"
}

# module housekeeping code - template code
function TemplateInitCode {
    Write-Host "Level 1 Init"
    $LoadModule | % { Import-Module ".\$_.psm1" }
}

TemplateInitCode 
try {
    ModuleSpecificInitCode 
} catch {
# Error handling
}

Test.ps1

# test.ps1
Remove-Module module.level*
Import-Module .\module.level1.psm1

При запуске test.ps1 вывод, который я получаю:

PS>.\test.ps1
Level 1 Init
Level 2 Init
Level 2 Code
Level 2 Code

Вопрос / Мой вопрос

Проблема в последней строке . Код уровня 2 работает вместо кода уровня 1.

Я пробовал local, private и script как <scope>:, но что бы я ни делал, Level 1 Code никогда не запускается.

Чего мне здесь не хватает, почему все модули работают в одном и том же пространстве имен?

1 Ответ

0 голосов
/ 14 мая 2018

Если вы явно не экспортируете что-либо из модуля, все это экспортируется.

Если вы хотите, чтобы функция была доступна только внутри модуля (подумайте о ней как о закрытой функции, хотя это не так).на самом деле относится к области действия Private: в PowerShell), затем просто экспортируйте все функции, кроме внутренних.

Export-ModuleMember - это способ определения того, что вы хотите экспортировать.Он принимает подстановочные знаки, поэтому, если вы можете описать общедоступный шаблон, вы можете сделать это за один вызов, но можно вызывать его столько раз, сколько вам нужно.

Как только функции больше не экспортируются,они не доступны для кода вне модуля.

Ваши примеры немного странны для меня, поскольку вы, похоже, хотите получить доступ к некоторому коду модуля вне модуля, но хотитеэто должно быть то же имя, но я не уверен.

В этом случае, например, если init1-й уровень должен был вызывать код в модуле Level2, вы можете подумать о добавлении -Scope Local к Import-Moduleпозвони сам, но я не уверен, что это поможет твоей ситуации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...