jeudi 11 juillet 2019

Powershell: Inherited classes calling Parent's empty constructors, even when passed objects

In powershell 5 I'm running into a strange inheritance problem with classes.

I want to enforce that we are passed an object during setup like [class]::new($mailbox_object), and I was intending to do this by causing [class]::new() to throw an error if it's associated object isn't assigned (say by a child constructor).

But powershell is calling empty parent constructors BEFORE calling the child constructor that was passed the object and I can't figure out if this is a bug or expected, and more importantly how to enforce that we have to be given an object at creation time

Design pattern speak: I'm trying to implement what I call a Unified Interface pattern, which is a Facade pattern to simplify/unify interactions with similar but differently typed objects, where actions for those objects are selected using a Strategy pattern and the the strategy is chosen automatically by the Facade when created (currently by trying to use an invisible Factory pattern)

IRL Example: trying to create a unified interface for Exchange Mailbox/Group objects, and implement a MemberOf function (to return which groups it's a member of). But Mailboxes and Groups use different commands (despite matching functionality) AND 365 and On Premises versions also use different commands (get-unifiedgroup instead of get-distributiongroup) so I'm trying to hide that complexity behind a unified Facade for clarity and usability

I'm open to changing my approach, particularly if there's a better way to do this. Just keep in mind there will be at minimum the following types of disparate objects each of which will need their own implementation of .MemberOf(): Interface_Mailbox_365, Interface_Mailbox_OnPremises, Interface_Group_365, Interface_Group_OnPremises, and I may implement Offline and Generic versions eventually.

MRE below, lines with > are the output. Since I've narrowed it to the an issue with the Interface creation, I've not included the Facade or Factory, but I can add them if they end up being needed.

class Interface_MailObject
{
    $MailObject = "Interface_MailObject class - initial"
    Interface_MailObject(){write-warning "Interface_MailObject::new() MailObject: {$($this.MailObject)}"}
}
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_Mailbox_365]::new("Mailbox Standin")

> 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}

Aucun commentaire:

Enregistrer un commentaire