2014-03-05 38 views
5

Ich baue ein Modul, das ein Cmdlet exportiert, das ich über mein Profil zur Verfügung stellen möchte. Die Implementierung dieses Cmdlets ist auf mehrere Implementierungsdateien verteilt, die Implementierungsfunktionen enthalten, die ich nicht öffentlich zugänglich machen möchte. Also verwende ich Export-ModuleMember, um sie zu verstecken.Powershell Moduldesign - Export-ModuleMember

get_something.psm1

import-module .\get_something_impl.psm1 

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

Export-ModuleMember -Function Get-Something 

ich dann get_something.psm1 zu meinem Profil hinzufügen. Durch den Export nur Get-Something bleiben alle meine Implementierungsfunktionen "privat".

Das Problem, das ich bei dem Verwenden des Export-ModuleMember-Befehls erfahre, muss ich ein Modul in meinen Implementierungsdateien jedes Mal importieren, wenn ich eine Funktion darin benötige. Angenommen, ich habe ein Modul person.psm1 mit einer Get-Person-Funktion, die ich in allen Implementierungsdateien aufrufen muss. Jetzt muss ich person.psm1 in jede einzelne Datei importieren, die ich Get-Person aufrufen muss. Dies ist ein Ergebnis der Verwendung von Export-ModuleMember -Function Get-Something. Ohne sie müsste ich person.psm1 nur einmal importieren und es wäre verfügbar.

Im Wesentlichen blockiert Export-ModuleMember nicht nur meine Implementierung nach außen, es blockiert es von meiner eigenen Implementierung.

Wird dies als normaler Aspekt beim Design von Powershell-Modulen erwartet und betrachtet?

Antwort

15

Dies war eigentlich ein wenig Debatte während der Entwicklung von Modulen. Ursprünglich war Export-ModuleMember erforderlich, um eine Funktion zu exportieren. Dies wurde langweilig und einschränkend. Daher sind standardmäßig alle Funktionen eines Moduls sichtbar, Variablen und Aliase jedoch nicht, solange Sie noch nie Export-ModuleMember innerhalb der .PSM1 verwendet haben.

Wenn Sie Export-ModuleMember verwenden, fängt es an, diese Liste einzuschränken. Es ist vielleicht keine schlechte Idee, eine kleinere Anzahl von Funktionen zu exportieren, aber Sie müssen es vorsichtig verwenden.

können Sie entweder schreiben:

Export-ModuleMember -Function a,b,c 

die einige Funktionen exportiert.

oder

Export-ModuleMember -Function * 

Letzteres entspricht insgesamt Export-Module zum Weglassen.

Sie können restriktivere Platzhalter verwenden, wenn Sie möchten, aber ich finde, dass 99% der Zeit, Sie brauchen sich überhaupt nicht damit zu beschäftigen.

Die andere Sache, die Sie zu fragen scheinen, ist, wie man Modulabhängigkeiten am besten behandelt. Heutzutage ist es ziemlich üblich, ein oder zwei Module beim Schreiben eines Skripts zu importieren, genauso wie es üblich ist, eine oder zwei Assemblys in ein C# -Projekt aufzunehmen. Wenn Sie dies innerhalb eines Moduls tun, können Sie das Flag "-Global" im Importmodul verwenden und die Verwendung von "-Force" vermeiden (wodurch das Modul erneut geladen wird). Dies macht es effizienter, das Modul in verschiedenen Funktionen wiederzuverwenden. Es macht es auch weniger wahrscheinlich, Probleme mit dem "Radfahren" (Entladen und Neuladen) des Moduls zu haben, was leider viele Module nicht gut machen.

Die Alternative zur Referenzierung des Moduls in jeder Funktion besteht in der Verwendung eines Modulmanifests (Get-Help New-ModuleManifest). Modulmanifeste sind sehr interessant und erfordern das Lernen für viele Teile der Modulentwicklung.Wenn Sie ein Modul in die Liste RequiredModules des Modulmanifests einschließen, wird es automatisch geladen, bevor das Modul importiert wird (zumindest in PowerShell 3 und höher). Wenn Sie ein Modul in die NestedModules-Liste des Modulmanifests einschließen, wird es als Teil des Moduls geladen, und die vom Modul exportierten Befehle werden stattdessen von Ihrem Modul exportiert.

Modul-Design ist ein schwieriges Biest, aber es ist sehr lohnend, richtig zu tun. Viel Glück.