Дизайн модуля PowerShell — Export-ModuleMember

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

Файл get_something.psm1

import-module .\get_something_impl.psm1

function Get-Something {
    [cmdletbinding()]
    Get-SomethingImplementation
}

Export-ModuleMember -Function Get-Something

Затем я добавляю get_something.psm1 в свой профиль. При экспорте только Get-Something все мои функции реализации остаются закрытыми.

Проблема, с которой я сталкиваюсь, заключается в том, что при использовании команды Export-ModuleMember мне приходится импортировать модуль в мои файлы реализации каждый раз, когда мне нужна функция внутри него. Например, предположим, что у меня есть модуль person.psm1 с функцией Get-Person, которую мне нужно вызывать во всех моих файлах реализации. Теперь я должен импортировать person.psm1 в каждый отдельный файл, который мне нужно вызвать Get-Person. Это результат использования Export-ModuleMember-Function Get-Something. Без него мне нужно было бы импортировать person.psm1 только один раз, и он был бы доступен.

По сути, Export-ModuleMember не только блокирует мою реализацию снаружи. Это блокирует его от моей собственной реализации.

Ожидается ли это и считается ли это нормальным аспектом разработки модулей PowerShell?


person Matthew S    schedule 05.03.2014    source источник


Ответы (1)


На самом деле это было небольшим спором во время разработки модулей. Первоначально для экспорта любой функции требовалось Export-ModuleMember. Это стало утомительным и ограничивающим. Таким образом, по умолчанию все функции из модуля видны, но переменные и псевдонимы — нет, если вы никогда не использовали Export-ModuleMember в .PSM1.

Если вы используете Export-ModuleMember, он начинает ограничивать этот список. Неплохой идеей может стать экспорт меньшего количества функций, но использовать его следует осторожно.

Вы можете либо написать:

Export-ModuleMember -Function a,b,c

который экспортирует несколько функций.

or

Export-ModuleMember -Function *

Последнее эквивалентно полному исключению Export-ModuleMember.

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

Другая вещь, которую вы, кажется, спрашиваете, это то, как лучше всего обрабатывать зависимости модулей. В настоящее время довольно распространено импортировать модуль или два при написании скрипта, точно так же, как довольно распространено включение одной или двух сборок в проект C#. Если вы делаете это внутри модуля, вы можете использовать флаг -Global для Import-Module и избегать использования -Force (который перезагрузит модуль). Это делает более эффективным повторное использование модуля в различных функциях. Это также снижает вероятность возникновения проблем с зацикливанием (выгрузкой и перезагрузкой) модуля, с чем, к сожалению, многие модули не справляются.

Альтернативой ссылке на модуль в каждой функции является использование манифеста модуля (Get-Help New-ModuleManifest). Манифесты модулей очень интересны и требуют изучения многих частей разработки модулей. Если вы включите модуль в список RequiredModules манифеста модуля, он будет автоматически загружен перед импортом модуля (по крайней мере, в PowerShell 3 и выше). Если вы включите модуль в список NestedModules манифеста модуля, он будет загружен как часть модуля, а команды, экспортированные модулем, будут экспортированы вместо этого вашим модулем.

Дизайн модуля — хитрый зверь, но очень полезно сделать все правильно. Удачи.

person Start-Automating    schedule 06.03.2014
comment
Можете ли вы подробнее рассказать о зацикливании модуля и привести пример того, как модули не справляются с этим? Почему Import-Module -Global это волшебное решение? Я считаю, что проблема с зацикливанием покрывается следующей проблемой GitHub (но, возможно, есть еще нюансы): github.com/PowerShell/PowerShell/issues/ - person John Zabroski; 19.03.2020