26 września 2011

PowerShell - antywzorzec kopiuj/wklej

Dlaczego lubię Add-Type


Pisząc skrypty w PowerShell'u, szczególnie takie jednorazowego użycia kuszącą opcją jest skorzystanie z cmdlet'u Add-Type. Umożliwia on rejestrację typu(-ów) danych zaimplementowanego w C#,VB.NET lub JScript i wykorzystanie go w skrypcie PowerShell'u. W moim przypadku gdy próbowałem użyć typów danych z .NET Framework w skrypcie otrzymałem następujący wyjątek.

Multiple ambiguous overloads found for ... and the argument count: ...

Runtime Powershell'a z jakiegoś powodu nie mógł dopasować odpowiedniej sygnatury metody z typem przekazywanych parametrów. Zamiast spędzić kolejne pół godziny nad hackowaniem kodu, użyłem magicznego cmdlet'u Add-Type.



Copy/Paste anti-pattern


Skopiowałem istniejący kod w C#, wypisałem referencje do zależnych assembly i wszystko zadziałało bez problemu.

$referencedAssemblies = ( 
 "System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
    "System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
    )

$sourceCodeInCSharp = @"
using System.Xml.Linq;

namespace XmlTest
{
    public class XmlGenerator
    {
        public void SaveFile(string filePath)
        {
            XDocument document = new XDocument();
            XElement rootElement = new XElement("root",
                new XElement("children",
                    new[]{
                new XElement("child1", "Child1Value"),
                new XElement("child2", "Child2Value")
            }));
            document.Add(rootElement);
            document.Save(filePath);
        }
    }
}
"@


if ([Type]::GetType("XmlTest.XmlGenerator") -eq $null) 
{
 Add-Type -ReferencedAssemblies $referencedAssemblies -TypeDefinition $sourceCodeInCSharp -Language CSharpVersion3
}

$generator = New-Object XmlTest.XmlGenerator;
$generator.SaveFile("test.xml");


Wynik działania skryptu jest następujący

<?xml version="1.0" encoding="utf-8"?>
<root>
  <children>
    <child1>Child1Value</child1>
    <child2>Child2Value</child2>
  </children>
</root>



Zatem, jeżeli nie lubisz Powershell'a, nie masz ochoty lub potrzeby kowertowania kodu z C#/VB.NET etc do PS to zachęcam z zapoznaniem sie z poleceniem Add-Type, które umożliwia także generowanie typów z plików kodu źródłowego.

Hope this helps.

Brak komentarzy:

Prześlij komentarz

Uwaga: tylko uczestnik tego bloga może przesyłać komentarze.