В powershell 5 я сталкиваюсь со странной проблемой наследования классов.
Я хочу обеспечить, чтобы нам передали объект во время установки, например [class]::new($mailbox_object)
, и я намеревался сделать это, заставив [class]::new()
выдать ошибку, если связанный объект не назначен (скажем, дочерним конструктором) ).
Но powershell вызывает пустых родительских конструкторов ПЕРЕД вызовом дочернего конструктора, которому был передан объект, и я не могу понять, является ли это ошибкой или ожидаемой, и что более важно, как обеспечить, чтобы мы имели получить объект во время создания
Шаблон проектирования говорит: я пытаюсь реализовать то, что я называю шаблоном Unified Interface, который представляет собой шаблон Facade, чтобы упростить / унифицировать взаимодействия с похожими, но по-разному типизированными объектами, где действия для этих объектов выбираются с использованием шаблона Strategy и Стратегия автоматически выбирается Фасадом при его создании (в настоящее время пытается использовать скрытую внутри Фасада невидимую Фабрику)
Пример IRL: попытка создать унифицированный интерфейс для объектов почтовых ящиков / групп Exchange и реализовать функцию MemberOf (для возврата групп, членом которых она является). Но почтовые ящики и группы используют разные команды (несмотря на соответствующую функциональность), а версии 365 и On Premises также используют разные команды (get-unifiedgroup вместо get-distributiongroup), поэтому я пытаюсь скрыть эту сложность за объединенным фасадом для ясности и удобства использования
Я готов изменить свой подход, особенно если есть лучший способ сделать это. Просто имейте в виду, что будут как минимум следующие типы разрозненных объектов, каждый из которых будет нуждаться в собственной реализации .MemberOf (): Interface_Mailbox_365
, Interface_Mailbox_OnPremises
, Interface_Group_365
, Interface_Group_OnPremises
, и я могу реализовать Offline и общие версии в конце концов.
MRE ниже, строки с> являются выводом. Поскольку я сузил это до проблемы с созданием интерфейса, я не включил Фасад или Фабрику, но я могу добавить их, если они в конечном итоге понадобятся.
class Interface_MailObject
{
$MailObject = "Interface_MailObject class - initial"
Interface_MailObject(){write-warning "Interface_MailObject::new() MailObject: {$($this.MailObject)}"}
static [Interface_MailObject] Build($object)
{
if
($object -eq "Mailbox Standin")
{return [Interface_Mailbox_365]::new($object)}
else
{throw("we don't reach here")}
}
}
Class Interface_Mailbox : Interface_MailObject
{
$MailObject = "Interface_Mailbox class - initial"
Interface_Mailbox () {write-warning "Interface_Mailbox::new() MailObject: {$($this.MailObject)}"}
Interface_Mailbox ($MailObject) {$this.MailObject = "Interface_Mailbox class - {$($MailObject)}"}
}
Class Interface_Mailbox_365 : Interface_Mailbox
{
$MailObject = "Interface_Mailbox_365 class - initial"
Interface_Mailbox_365 () {write-warning "Interface_Mailbox_365::new() MailObject: {$($this.MailObject)}"}
Interface_Mailbox_365 ($MailObject) {$this.MailObject = "Interface_Mailbox_365 class - {$($MailObject)}"}
[object[]] MemberOf(){throw("Interface_Mailbox_365.MemberOf TBD")}
}
[Interface_MailObject]::new("Mailbox Standin")|tee -va a
> WARNING: Interface_MailObject::new() MailObject: {Interface_Mailbox_365 class - initial}
> WARNING: Interface_Mailbox::new() MailObject: {Interface_Mailbox_365 class - initial}
>
> MailObject
> ----------
> Interface_Mailbox_365 class - {Mailbox Standin}
Обратите внимание, что даже несмотря на то, что мы вызвали [Interface_Mailbox_365]::new("Mailbox Standin")
powershell, выполнил пустой конструктор прародителя, затем пустой конструктор родителя, прежде чем запустить тот, который мы вызвали.
Если бы они выполнялись в другом порядке, было бы хорошо. Если бы они вызывали родительские конструкторы, которые совпадают с одним и тем же параметром qty и типом, это также было бы хорошо
Но это не так, и я не знаю, как решить это без использования какой-то странной акробатики с фабрикой Singleton, которая кажется чрезмерным количеством микроуправления для чего-то, что должно быть обычной потребностью (требующий входной параметр во время инициализации ) так что я думаю, что я что-то упускаю