Pregunta

Cuando uso otro objeto en .NET-Framework en C#, puedo guardar mucho tipeo usando la directiva usando.

using FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It;

...


  var blurb = new Thingamabob();

...

Entonces, ¿hay alguna manera en PowerShell para hacer algo similar? Estoy accediendo a muchos objetos .net y no estoy contento de tener que escribir

 $blurb = new-object FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It.Thingamabob;

todo el tiempo.

¿Fue útil?

Solución

PowerShell 5.0 (incluido en WMF5 o Windows 10 y UP), agrega el using namespace construir al idioma. Puedes usarlo en tu script así:

#Require -Version 5.0
using namespace FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It
$blurb = [Thingamabob]::new()

(Los #Require La declaración en la primera línea no es necesaria para usar using namespace, pero evitará que el script se ejecute en PS 4.0 y abajo donde using namespace es un error de sintaxis).

Otros consejos

Realmente no hay nada a nivel de espacio de nombres como ese. A menudo asigno tipos de uso común a las variables y luego las instancias:

$thingtype = [FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It.Thingamabob];
$blurb = New-Object $thingtype.FullName

Probablemente no valga la pena si el tipo no se usará repetidamente, pero creo que es lo mejor que puede hacer.

Mira esta publicación de blog de hace un par de años: http://blogs.msdn.com/richardb/archive/2007/02/21/add-types-ps1-poor-man-s-using-for-powershell.aspx

Aquí está add-types.ps1, Extraído de ese artículo:

param(
    [string] $assemblyName = $(throw 'assemblyName is required'),
    [object] $object
)

process {
    if ($_) {
        $object = $_
    }

    if (! $object) {
        throw 'must pass an -object parameter or pipe one in'
    }

    # load the required dll
    $assembly = [System.Reflection.Assembly]::LoadWithPartialName($assemblyName)

    # add each type as a member property
    $assembly.GetTypes() | 
    where {$_.ispublic -and !$_.IsSubclassOf( [Exception] ) -and $_.name -notmatch "event"} | 
    foreach { 
        # avoid error messages in case it already exists
        if (! ($object | get-member $_.name)) {
            add-member noteproperty $_.name $_ -inputobject $object
        }
    }
}

Y para usarlo:

RICBERG470> $tfs | add-types "Microsoft.TeamFoundation.VersionControl.Client"
RICBERG470> $itemSpec = new-object $tfs.itemspec("$/foo", $tfs.RecursionType::none)

Básicamente, lo que hago es rastrear el ensamblaje para los tipos no triviales, luego escribir un "constructor" que use Add-Member Agregarlos (de manera estructurada) a los objetos que me importan.

Vea también esta publicación de seguimiento: http://richardberg.net/blog/?p=38

Esto es solo una broma, broma ...

$fullnames = New-Object ( [System.Collections.Generic.List``1].MakeGenericType( [String]) );

function using ( $name ) { 
foreach ( $type in [Reflection.Assembly]::LoadWithPartialName($name).GetTypes() )
    {
        $fullnames.Add($type.fullname);
    }
}

function new ( $name ) {
    $fullname = $fullnames -like "*.$name";
    return , (New-Object $fullname[0]);
}

using System.Windows.Forms
using FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It
$a = new button
$b = new Thingamabob

Aquí hay algún código que funciona en PowerShell 2.0 para agregar alias de tipo. Pero el problema es que no está alcanzado. Con un poco de trabajo adicional, podría "no importar" los espacios de nombres, pero esto debería llevarlo a un buen comienzo.

##############################################################################
#.SYNOPSIS
# Add a type accelerator to the current session.
#
#.DESCRIPTION
# The Add-TypeAccelerator function allows you to add a simple type accelerator
# (like [regex]) for a longer type (like [System.Text.RegularExpressions.Regex]).
#
#.PARAMETER Name
# The short form accelerator should be just the name you want to use (without
# square brackets).
#
#.PARAMETER Type
# The type you want the accelerator to accelerate.
#
#.PARAMETER Force
# Overwrites any existing type alias.
#
#.EXAMPLE
# Add-TypeAccelerator List "System.Collections.Generic.List``1"
# $MyList = New-Object List[String]
##############################################################################
function Add-TypeAccelerator {

    [CmdletBinding()]
    param(

        [Parameter(Position=1,Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
        [String[]]$Name,

        [Parameter(Position=2,Mandatory=$true,ValueFromPipeline=$true)]
        [Type]$Type,

        [Parameter()]
        [Switch]$Force

    )

    process {

        $TypeAccelerators = [Type]::GetType('System.Management.Automation.TypeAccelerators')

        foreach ($a in $Name) {
            if ( $TypeAccelerators::Get.ContainsKey($a) ) {
                if ( $Force ) {
                    $TypeAccelerators::Remove($a) | Out-Null
                    $TypeAccelerators::Add($a,$Type)
                }
                elseif ( $Type -ne $TypeAccelerators::Get[$a] ) {
                    Write-Error "$a is already mapped to $($TypeAccelerators::Get[$a])"
                }
            }
            else {
                $TypeAccelerators::Add($a, $Type)
            }
        }

    }

}

Si solo necesita crear una instancia de su tipo, puede almacenar el nombre del espacio de nombres largo en una cadena:

$st = "System.Text"
$sb = New-Object "$st.StringBuilder"

No es tan poderoso como el using Directiva en C#, pero al menos es muy fácil de usar.

Gracias a todos por su aporte. He marcado la contribución de Richard Berg como una respuesta, porque se parece más a lo que estoy buscando.

Todas tus respuestas me trajeron en la pista que parece más prometedor: en Su publicación de blog Keith Dahlby propone un comandro de tipo Get-Type que permite una fácil consución de tipos para métodos genéricos.

Creo que no hay razón en contra de exetender esto para buscar también a través de una ruta predefinida de ensamblajes para un tipo.

Descargo de responsabilidad: No he construido eso, todavía ...

Así es como uno podría usarlo:

$path = (System.Collections.Generic, FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It)

$type = get-type -Path $path List Thingamabob
$obj = new-object $type
$obj.GetType()

Esto daría como resultado una buena lista genérica de Thingamabob. Por supuesto, concluiría todo sin la definición de ruta en solo otra función de utilidad. El tipo de Get-Type incluiría un paso para resolver cualquier tipo dado nuevamente la ruta.

#Requires -Version 5
using namespace System.Management.Automation.Host
#using module

Me doy cuenta de que esta es una publicación antigua, pero estaba buscando lo mismo y encontré esto: http://weblogs.asp.net/adweigert/powershell-adding-the-Using-statement

Editar: supongo que debería especificar que le permite usar la sintaxis familiar de ...

using ($x = $y) { ... }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top