Skip to content

Expose a non-owning wrapper factory for an existing cOAPI #1

Description

@tadoEng

Why

EtabExtension.CLI Closed Alpha remediation has reached a real lifecycle boundary that EtabSharp 0.3.5-beta cannot express safely.

Live evidence in tadoEng/EtabExtension.CLI#15 showed the managed path Process.Start(ETABS.exe) -> ETABSWrapper.ConnectToProcess(pid) could return an object whose SapModel existed but was not API-ready: cSapModel.InitializeNewModel threw and ApplicationExit(false) returned -1 on the same freshly attached object. Cardex ETABS 23.3 evidence confirms cHelper.CreateObject(path) starts the target program, cOAPI.ApplicationStart() is the explicit startup call, and InitializeNewModel is for a properly created API object.

The CLI therefore needs to own the raw CSI lifecycle (cHelper / cOAPI) and exact OS-process identity, then hand the same already-created, already-started cOAPI to EtabSharp for model/domain abstractions. EtabSharp 0.3.5-beta has no public way to do that: ETABSApplication(cOAPI, ...) is internal.

Do not solve this by using CreateNew(startApplication:true): current CreateNew logs but does not propagate nonzero ApplicationStart, and the CLI needs the raw return code as part of its safety contract. Do not use ConnectToProcess: its GetObjectProcess path can fall back to ROT GetObject, which is incompatible with exact-PID ownership.

Required API

Add one deliberately low-level public factory, conceptually:

public static ETABSApplication WrapExisting(
    cOAPI api,
    int majorVersion,
    double apiVersion,
    string fullVersion,
    ILogger<ETABSApplication>? logger = null)

Exact naming may differ, but the semantics must not.

Contract

This method is pure wrapping. It must:

  • validate api and supplied metadata;
  • construct the existing ETABSApplication around that exact cOAPI;
  • use the existing api.SapModel path;
  • preserve the exact object identity supplied by the caller.

It must not:

  • call cHelper.CreateObject*;
  • call ApplicationStart;
  • call GetObject, GetObjectProcess, or any ROT attach;
  • enumerate or select ETABS processes;
  • call Hide / Unhide;
  • call ApplicationExit;
  • silently create or attach to another ETABS instance.

Keep the ETABSApplication constructor internal; the public entry point should communicate the non-owning/raw-interop intent clearly.

Ownership / disposal

The caller owns application lifecycle. Wrapping an existing cOAPI must not imply that EtabSharp owns process startup or shutdown. Current ETABSApplication.Dispose() only releases COM references; preserve that non-exiting behavior.

Document that callers must perform lifecycle calls themselves when using this factory.

Verification

  • API is additive; existing Connect / ConnectToProcess / CreateNew behavior remains unchanged in this issue.
  • Add focused tests/documentation proving the new factory does not bootstrap or attach another application.
  • Build/test both supported targets.
  • No live ETABS mutation is needed merely to prove the factory surface.
  • Use Cardex for any CSI API fact referenced during implementation; do not commit proprietary/generated Cardex content.

Downstream

This is a blocking dependency for EtabExtension.CLI TAD-19 / PR #15. After this change is reviewed, release it as the next beta package version (expected 0.3.6-beta, unless repository release policy dictates otherwise), then the CLI can implement raw CSI startup + exact OS ownership + InitializeNewModel before wrapping the proven-ready handle.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions