2017-01-24 2 views
3

PowerShell에서 이벤트를 사용하여 책임을 분리하고 모듈 간의 종속성을 제거하고자합니다. 하위 모듈은 상위 모듈에 활동을 알리고 이벤트를 발생시킬 때 상위 모듈로부터 정보를 필요로하는 경우가 있습니다.PowerShell에서 엔진 이벤트 처리기의 반환 값을 가져 오는 방법은 무엇입니까?

이것은 내가 지금까지 시도한 것입니다. 실세계 시나리오에서는 부모 모듈에 등록, 등록 해제 및 처리기 기능 부품을 배치하고 하위 모듈에 New-Event 부품을 배치합니다.

function MyHandler { 

    param (
    [System.Management.Automation.PSEventArgs]$Event 
) 

    Write-Host "In MyHandler now!" -ForegroundColor Yellow 

    Write-Host "Sender  : $($Event.Sender)" 
    Write-Host "SourceArgs : $($Event.SourceArgs)" 
    Write-Host "MessageData : $($Event.MessageData)" 
    Write-Host "TimeGenerated : $($Event.TimeGenerated)" 

    $Event.MessageData = "This does not make it back." 

    return "Neither does this." 
} 

# subscribe 
[String]$MessageData = "Input" 
Register-EngineEvent -SourceIdentifier Pipo -Action {MyHandler $Event } 

# raise event and see what we get back 
New-Event -Sender "Me" -SourceIdentifier "Pipo" -EventArguments "MyEventArgs" -MessageData $MessageData 

# cleanup 
Unregister-Event -SourceIdentifier Pipo 

는가 MyHandler에 대한 호출을 트리거 않으며, 내가 전달 된 인수 및 이벤트 속성에 액세스 할 수 있습니다. 문제는 이벤트 처리기 함수에서 이벤트의 기수까지 데이터를 다시 가져올 수있는 방법을 찾을 수 없다는 것입니다. 내 사고 방식은 아마도 너무 많이 C# 지향적인데, 나는 PS에서 다르게 가야하는 방식으로 일을하려 할 수도있다. 이벤트를 발생시키기 위해 객체를 생성하고 파이프 라인으로 보내는 개념은 모두 이상하게 보입니다. 그리고 실제로 일어나는 일을 이해하지 못합니다.

어떻게해야할까요?

+1

'Receive-Job ' – PetSerAl

+0

오히려 ... 이것은 처리기의 "반환 값"을 제공하지만 이벤트를 발생시키는 하위 모듈은 작업에 대해 알지 못합니다 부모 모듈에있는 Register-EngineEvent 호출의 결과로,이 경우 작업이 자식 모듈의 것 인 New-Event의 결과로 좋았을 것입니다. 그래서 이것은 무의미하고 백그라운드 작업을 실행하기에 좋지만 이벤트 시스템에는 적합하지 않습니다. 내 필요에 맞는 잘못된 PowerShell 기능을보고 있습니까? –

+0

* 내 필요에 맞는 잘못된 PowerShell 기능을 찾고 있습니까? * IMHO, 예. 원하는 경우 부모 모듈의 해당 코드를 하위 모듈에서 호출 할 수 있으며 전역 모듈로 만들 수 있습니다. 그리고 이벤트를 발생시키는 대신이 전역 함수를 호출하십시오. – PetSerAl

답변

0

내 요구를 해결하는 방법을 찾았습니다.

Pass a function as a parameter in PowerShell

내가 전체 예로 일했다 : 그것은 PowerShell 및 콜백을 검색 할 때 나는 나에게 많은 도움이 질문에 (특히 던컨의 답변을) 발견, 잘못된 키워드를 검색했다 밝혀졌습니다. 이것은 클라이언트 스크립트, "Client.ps1"로 저장하는 것입니다

Import-Module -Name ".\Server.psm1" -DisableNameChecking 

$script:ClientVar = "Not seen by server, returned by event handler." 

function Handle_Initialized { 
    Write-Host "Handler Initialized is being called." 

    # a return value is optional 
    return "=== $script:ClientVar ===" 
} 

function Handle_ProcessedData { 

    param (
    $Argument1, 
    $Argument2, 
    $Argument3 
) 

    Write-Host "Handler ProcessedData is called." 
    Write-Host "Arguments are $argument1, $argument2 and $argument3." 

    # a return value is optional 
    return "=== $argument1, $argument2, $argument3 ===" 
} 


Subscribe-Event -Name Initialized -Handler $function:Handle_Initialized 
Subscribe-Event -Name ProcessedData -Handler $function:Handle_ProcessedData 

Write-Host "" 
Write-Host "calling with active subscriptions" 
Write-Host "=================================" 

Do-ServerStuff 

Unsubscribe-Event -Name Initialized 
Unsubscribe-Event -Name ProcessedData 

Write-Host "" 
Write-Host "calling again with no active subscriptions" 
Write-Host "=================================" 

Do-ServerStuff 

Remove-Module -Name "Server" 

그런 다음, 같은 폴더에 "Server.psm1"로 이것을 넣어 :

[ScriptBlock]$script:Handler_Initialized = $null 
[ScriptBlock]$script:Handler_ProcessedData = $null 

function Subscribe-Event { 

    param (
    [String]$Name, 
    [ScriptBlock]$Handler 
) 

    switch ($Name) { 
    Initialized { $script:Handler_Initialized = $Handler } 
    ProcessedData { $script:Handler_ProcessedData = $Handler } 
    } 
} 

function Unsubscribe-Event { 

    param (
    [String]$Name 
) 

    switch ($Name) { 
    Initialized { $script:Handler_Initialized = $null } 
    ProcessedData { $script:Handler_ProcessedData = $null } 
    } 
} 

function Raise-Initialized { 

    param (
) 

    if ($script:Handler_Initialized) { 
    return & $script:Handler_Initialized 
    } 
} 

function Raise-ProcessedData { 

    param (
    [Object]$Argument1, 
    [Object]$Argument2, 
    [Object]$Argument3 
) 

    if ($script:Handler_ProcessedData) { 
    return & $script:Handler_ProcessedData -Argument1 $Argument1 -Argument2 $Argument2 -Argument3 $Argument3 
    } 
} 

function Do-ServerStuff { 
    Write-Host "Before raising event Initialized." 
    Raise-Initialized 
    Write-Host "After raising event Initialized." 
    Write-Host "" 
    Write-Host "Before raising event ProcessedData." 
    Raise-ProcessedData -Argument1 "AAA" -Argument2 "BBB" -Argument3 "CCC" 
    Write-Host "After raising event ProcessedData." 
} 

그리고 당신은 발견 할 것이다 확장 가능한 동기 이벤트 처리 시스템이 있다는 것을 알았습니다.

대부분의 배관은 서버 모듈에있어 처리기 기능의 프로토 타입을 지정합니다. 클라이언트 코드는 이벤트를 구독하고 구독을 취소하고 핸들러 구현을 제공하기 만합니다. 일반적인 PowerShell 방식으로 모든 핸들러에 대한 명명 된 매개 변수와 반환 값 (실제 출력 값)을 지원합니다. 서버는 내가 좋아하는 클라이언트에 대해 아무것도 모릅니다. 의존성은 한 가지 방법 밖에 없습니다.

예를 들어,이 구성표를 사용하면 순수 코어 로직을 수행하는 모듈을 빌드 할 수 있습니다. 일부 전역 객체를 통해 로깅하는 대신 서버 모듈에서 메시지를 보내는 이벤트를 발생 시키면 클라이언트는 메시지를 보낼 이벤트와 보낼 위치를 결정할 수 있습니다. 이렇게하면 서버 모듈의 유용성이 높아져 테스트 할 수 있습니다.

나는 맛의 문제일지도 모른다, 나는 일반적으로 의존성 주입에 사건을 사용하여 호의를 보인다. 의존성 삽입을 사용하면 서버는 여전히 주입 된 유형에 대해 알 필요가 있습니다.

즐기십시오!

관련 문제