Question Exemple : PS v3 et la DLR

Plus d'informations
il y a 10 ans 3 mois #16720 par Laurent Dardenne
Depuis la version 3 de PowerShell l'implémentation des objets a été réécrit autour de la DLR (framework dotnet 4.0) qui, comme indiqué ici , 'ajoute un ensemble de services au CLR pour une meilleure prise en charge des langages dynamiques.'.
Sans rentrer dans les détails, voici un court exemple de création d'un objet que la DLR permet :
[code:1]
#Crée un object dynamique
$O = new-object System.Dynamic.ExpandoObject

#C'est bien un PSObject
$O -IS [PSObject]
#True

$O.PSObject.Typenames
#Mais son type ne le réfléte pas
#System.Dynamic.ExpandoObject
#System.Object

$O
#Ras

$O|gm
#Erreur gm : Aucun objet n'a été spécifié à l'applet de commande get-member.

,$o|gm
# TypeName : System.Dynamic.ExpandoObject
#
# Name MemberType Definition
# ----

# Add Method void IDictionary[string,Object].Add(string key, System.Object value), vo...
#...

$o.psbase|gm
#renvoi un System.Management.Automation.PSMemberSet

$O.Nom=10 #crée dynamiquement une propriété
$O.Informations=@{adresse='20 rue des beignes'} #Puis une seconde

#Affiche une hashtable (de type Dictionary<TKey, TValue> ) !
$O
# Key Value
# ---
# Nom 10
# Informations {adresse}

# Nouvelle demande de Get-Member
$O|gm
# TypeName : System.Collections.Generic.KeyValuePair`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral,
# PublicKeyToken=b77a5c561934e089],[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral,
# PublicKeyToken=b77a5c561934e089]]
#
# Name MemberType Definition
# ----

# Equals Method bool Equals(System.Object obj)

#Ajoutons un membre personnalisé
Add-Member -InputObject $O -MemberType ScriptMethod -Name ToString -Value {\"Adresse : $($this.Informations.adresse)\"} -Force
#ou ,$O|Add-Member -MemberType ScriptMethod -Name ToString -Value {\"Adresse : $($this.Informations.adresse)\"} -Force

\"$o\" #Ce type d'affichage n'appel pas la méthode ToString
#[Nom, 10] [Informations, System.Collections.Hashtable]

#Appelons là directement
$O.ToString()
#Adresse : 20 rue des beignes
#
#Cela fonctionne, $This est bien reconnu dans le scriptblock du membre déclaré

#Essayons de supprimer un membre
$O.psobject.members.remove('Nom')
$O
#L'appel ne fonctionne pas

#essayons la méthode Remove de la classe System.Dynamic.ExpandoObject
$O.Remove('Nom')
#Erreur : Surcharge introuvable pour « Remove » et le nombre d'arguments « 1 ».
[/code:1]
A partir d'ici, cela se complique, car Powershell ne sait pas manipuler directement des interfaces :/
Comme le problème est connu, le MVP Oisin Grehan a créé une fonction Get-Interface qui règle ce problème.
L'interface à récupérer étant une interface générique on tombe sur une autre faiblesse de Powershell, à savoir que le nom des types doit être des noms complet:
[code:1]
$O.Remove
# OverloadDefinitions
#
# bool IDictionary[string,Object].Remove(string key)
#...
[/code:1]
On doit récupérer le type de l'interface Dictionary<TKey, TValue> puis son nom complet :
[code:1]
$TypeInterface=($O.GetType().GetInterfaces()|Where {$_.Name -eq 'IDictionary`2'}).FullName
#System.Collections.Generic.IDictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77
#a5c561934e089],[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
[/code:1]
Une fois l'interface accessible, il reste à l'appeler :
[code:1]
$IRemove=Get-Interface $O $TypeInterface
$IRemove.Remove('Nom')>$null
$O
# Key Value
# ---
# Informations {adresse}
[/code:1]
Comme indiqué sur la mailing list des MVP, on peut déclarer des méthodes :
[code:1]
$O.Nom='PS' #recrée le membre
$O.GetNom = { \"{0} {1}\" -f $this.Nom,$this.Informations.Adresse }
$O.GetNom()
#Impossible d'appeler la méthode.
$O.GetNom.Invoke()
#$this inconnu dans ce contexte

#redéclare la méthode dynamiquement
$O.GetNom = { param($x) \"{0} {1}\" -f $x.Nom,$x.Informations.Adresse }
$O.GetNom.Invoke($O)
#OK !
[/code:1]
Cela nous fait donc une manière de plus pour créer des objets.<br><br>Message édité par: Laurent Dardenne, à: 26/12/13 18:07

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.065 secondes
Propulsé par Kunena