Синглтон Powershell и это поведение - PullRequest
1 голос
/ 28 марта 2020

Я нахожусь в муках крупного рефактора и образования PS OOP, с текущими топи c, являющимися синглетонами. У меня есть некоторые данные о состоянии программы, которые я хочу сделать доступными в одноэлементном режиме, и я вижу странное поведение.

Это работает для первых двух строк записи, но затем зависает на третьей, которая ссылается на второй класс.

class PxStatus {
    static [PxStatus] $singleton = $null
    [string]$Context = 'machine'
    [datetime]$StartTime = (Get-Date)

    static [PxStatus] Get() {
        if ([PxStatus]::singleton -eq $null) {
            [PxStatus]::singleton = [PxStatus]::new()
        }

        return [PxStatus]::singleton
    }
}

class pxLogFile {
    # Properties
    static [pxLogFile] $singleton = $null
    [string] $nameSeed = "PxTools $(([PxStatus]::Get()).Context) context"
    [string] $path = "$env:TEMP\$(([pxLogFile]::Get()).nameSeed) $((get-date).toString('yyyy-MM-dd-hh-mm-ss')).log"

    static [pxLogFile] Get() {
        if ([pxLogFile]::singleton -eq $null) {
            [pxLogFile]::singleton = [pxLogFile]::new()

        return [pxLogFile]::singleton
    }
}



CLS
Write-Host "$(([PxStatus]::Get()).Context)"
Write-Host "$(([PxStatus]::Get()).StartTime)"
Write-Host "$(([pxLogFile]::Get()).path)"

Однако, если я обращаюсь к пути в конструкторе, вот так, он работает.

class PxStatus {
    static [PxStatus] $singleton = $null
    [string]$Context = 'machine'
    [datetime]$StartTime = (Get-Date)

    static [PxStatus] Get() {
        if ([PxStatus]::singleton -eq $null) {
            [PxStatus]::singleton = [PxStatus]::new()

            #([PxStatus]::singleton).Context = 'machine'
            #([PxStatus]::singleton).StartTime = Get-Date
        }

        return [PxStatus]::singleton
    }
}

class pxLogFile {
    # Properties
    static [pxLogFile] $singleton = $null
    [string] $nameSeed = "PxTools $(([PxStatus]::Get()).Context) context"
    [string] $path = $null

    static [pxLogFile] Get() {
        if ([pxLogFile]::singleton -eq $null) {
            [pxLogFile]::singleton = [pxLogFile]::new()

            ([pxLogFile]::singleton).Path = "$env:TEMP\$(([pxLogFile]::Get()).nameSeed) $((get-date).toString('yyyy-MM-dd-hh-mm-ss')).log"
        }

        return [pxLogFile]::singleton
    }
}



CLS
Write-Host "$(([PxStatus]::Get()).Context)"
Write-Host "$(([PxStatus]::Get()).StartTime)"
Write-Host "$(([pxLogFile]::Get()).path)

Я предполагаю, что проблема заключается в доступе к свойству в тот же синглтон, что и для nameSeed. В качестве альтернативы я также могу использовать это в определении свойства.

[string] $path = "$env:TEMP\$($this.nameSeed) $((get-date).toString('yyyy-MM-dd-hh-mm-ss')).log"

Что, честно говоря, в любом случае более читабельно. Мне просто интересно, что именно происходит с той первой, которая вызывает сбой? Создаю ли я какое-то странное условие l oop, не используя $this?

1 Ответ

1 голос
/ 29 марта 2020

Вызов [pxLogFile]::Get(), вложенный внутрь

[string] $path = "$env:TEMP\$(([pxLogFile]::Get()).nameSeed) $((get-date).toString('yyyy-MM-dd-hh-mm-ss')).log"

, вызывает бесконечную рекурсию, которая в конечном итоге приводит к переполнению стека.

Просто напрямую ссылаются на $nameSeed, остальные данные c свойство, при инициализации $path:

class pxLogFile {
    # Properties
    static [pxLogFile] $singleton = $null
    [string] $nameSeed = "PxTools $(([PxStatus]::Get()).Context) context"
    # Refer to $nameSeed instead of to [pxLogFile]::Get()).nameSeed
    [string] $path = "$env:TEMP\$($nameSeed) $((get-date).toString('yyyy-MM-dd-hh-mm-ss')).log"

    static [pxLogFile] Get() {
        if ($null -eq [pxLogFile]::singleton) {
            [pxLogFile]::singleton = [pxLogFile]::new()
        }
        return [pxLogFile]::singleton
    }
}


Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...