using System; using ArchestrA.MxAccess; namespace ZB.MOM.WW.MxGateway.Worker.MxAccess; /// /// Adapter exposing MXAccess COM object methods through the /// interface. /// /// /// The supplied object must implement the typed MXAccess COM interface contract. /// In production it is the LMXProxyServerClass RCW, which implements /// / / /// . Tests substitute a typed fake that /// implements directly. The earlier late-bound /// Type.InvokeMember reflection fallback was removed: it bypassed the /// typed interface contract, boxed value-type handles on every call, and only /// ever served test doubles — a typed fake is the supported test seam now. /// public sealed class MxAccessComServer : IMxAccessServer { private readonly object mxAccessComObject; /// /// Initializes the adapter with the MXAccess COM object. /// /// /// MXAccess COM object instance. Must implement either the typed /// COM interface family (production) or /// directly (test fakes). /// public MxAccessComServer(object mxAccessComObject) { this.mxAccessComObject = mxAccessComObject ?? throw new ArgumentNullException(nameof(mxAccessComObject)); } /// public int Register(string clientName) { if (mxAccessComObject is IMxAccessServer typedFake) { return typedFake.Register(clientName); } return AsProxyServer().Register(clientName); } /// public void Unregister(int serverHandle) { if (mxAccessComObject is IMxAccessServer typedFake) { typedFake.Unregister(serverHandle); return; } AsProxyServer().Unregister(serverHandle); } /// public int AddItem( int serverHandle, string itemDefinition) { if (mxAccessComObject is IMxAccessServer typedFake) { return typedFake.AddItem(serverHandle, itemDefinition); } return AsProxyServer().AddItem(serverHandle, itemDefinition); } /// public int AddItem2( int serverHandle, string itemDefinition, string itemContext) { if (mxAccessComObject is IMxAccessServer typedFake) { return typedFake.AddItem2(serverHandle, itemDefinition, itemContext); } return AsProxyServer3().AddItem2(serverHandle, itemDefinition, itemContext); } /// public void RemoveItem( int serverHandle, int itemHandle) { if (mxAccessComObject is IMxAccessServer typedFake) { typedFake.RemoveItem(serverHandle, itemHandle); return; } AsProxyServer().RemoveItem(serverHandle, itemHandle); } /// public void Advise( int serverHandle, int itemHandle) { if (mxAccessComObject is IMxAccessServer typedFake) { typedFake.Advise(serverHandle, itemHandle); return; } AsProxyServer().Advise(serverHandle, itemHandle); } /// public void UnAdvise( int serverHandle, int itemHandle) { if (mxAccessComObject is IMxAccessServer typedFake) { typedFake.UnAdvise(serverHandle, itemHandle); return; } AsProxyServer().UnAdvise(serverHandle, itemHandle); } /// public void AdviseSupervisory( int serverHandle, int itemHandle) { if (mxAccessComObject is IMxAccessServer typedFake) { typedFake.AdviseSupervisory(serverHandle, itemHandle); return; } AsProxyServer4().AdviseSupervisory(serverHandle, itemHandle); } /// public object Suspend( int serverHandle, int itemHandle) { if (mxAccessComObject is IMxAccessServer typedFake) { return typedFake.Suspend(serverHandle, itemHandle); } AsProxyServer4().Suspend(serverHandle, itemHandle, out MxStatus status); return status; } /// public object Activate( int serverHandle, int itemHandle) { if (mxAccessComObject is IMxAccessServer typedFake) { return typedFake.Activate(serverHandle, itemHandle); } AsProxyServer4().Activate(serverHandle, itemHandle, out MxStatus status); return status; } /// public int AuthenticateUser( int serverHandle, string verifyUser, string verifyUserPassword) { if (mxAccessComObject is IMxAccessServer typedFake) { return typedFake.AuthenticateUser(serverHandle, verifyUser, verifyUserPassword); } return AsProxyServer().AuthenticateUser(serverHandle, verifyUser, verifyUserPassword); } /// public int ArchestrAUserToId( int serverHandle, string userIdGuid) { if (mxAccessComObject is IMxAccessServer typedFake) { return typedFake.ArchestrAUserToId(serverHandle, userIdGuid); } return AsProxyServer2().ArchestrAUserToId(serverHandle, userIdGuid); } /// public int AddBufferedItem( int serverHandle, string itemDefinition, string itemContext) { if (mxAccessComObject is IMxAccessServer typedFake) { return typedFake.AddBufferedItem(serverHandle, itemDefinition, itemContext); } return AsProxyServer5().AddBufferedItem(serverHandle, itemDefinition, itemContext); } /// public void SetBufferedUpdateInterval( int serverHandle, int updateIntervalMilliseconds) { if (mxAccessComObject is IMxAccessServer typedFake) { typedFake.SetBufferedUpdateInterval(serverHandle, updateIntervalMilliseconds); return; } AsProxyServer5().SetBufferedUpdateInterval(serverHandle, updateIntervalMilliseconds); } /// public void Write( int serverHandle, int itemHandle, object? value, int userId) { if (mxAccessComObject is IMxAccessServer typedFake) { typedFake.Write(serverHandle, itemHandle, value, userId); return; } AsProxyServer().Write(serverHandle, itemHandle, value!, userId); } /// public void Write2( int serverHandle, int itemHandle, object? value, object? timestamp, int userId) { if (mxAccessComObject is IMxAccessServer typedFake) { typedFake.Write2(serverHandle, itemHandle, value, timestamp, userId); return; } AsProxyServer4().Write2(serverHandle, itemHandle, value!, timestamp!, userId); } /// public void WriteSecured( int serverHandle, int itemHandle, int currentUserId, int verifierUserId, object? value) { if (mxAccessComObject is IMxAccessServer typedFake) { typedFake.WriteSecured(serverHandle, itemHandle, currentUserId, verifierUserId, value); return; } AsProxyServer().WriteSecured(serverHandle, itemHandle, currentUserId, verifierUserId, value!); } /// public void WriteSecured2( int serverHandle, int itemHandle, int currentUserId, int verifierUserId, object? value, object? timestamp) { if (mxAccessComObject is IMxAccessServer typedFake) { typedFake.WriteSecured2(serverHandle, itemHandle, currentUserId, verifierUserId, value, timestamp); return; } AsProxyServer4().WriteSecured2(serverHandle, itemHandle, currentUserId, verifierUserId, value!, timestamp!); } private ILMXProxyServer AsProxyServer() { return mxAccessComObject as ILMXProxyServer ?? throw new InvalidOperationException( $"MXAccess COM object of type '{mxAccessComObject.GetType().FullName}' does not implement " + $"{nameof(ILMXProxyServer)} or {nameof(IMxAccessServer)}."); } private ILMXProxyServer2 AsProxyServer2() { return mxAccessComObject as ILMXProxyServer2 ?? throw new InvalidOperationException( $"MXAccess COM object of type '{mxAccessComObject.GetType().FullName}' does not implement " + $"{nameof(ILMXProxyServer2)} or {nameof(IMxAccessServer)}."); } private ILMXProxyServer3 AsProxyServer3() { return mxAccessComObject as ILMXProxyServer3 ?? throw new InvalidOperationException( $"MXAccess COM object of type '{mxAccessComObject.GetType().FullName}' does not implement " + $"{nameof(ILMXProxyServer3)} or {nameof(IMxAccessServer)}."); } private ILMXProxyServer4 AsProxyServer4() { return mxAccessComObject as ILMXProxyServer4 ?? throw new InvalidOperationException( $"MXAccess COM object of type '{mxAccessComObject.GetType().FullName}' does not implement " + $"{nameof(ILMXProxyServer4)} or {nameof(IMxAccessServer)}."); } private ILMXProxyServer5 AsProxyServer5() { return mxAccessComObject as ILMXProxyServer5 ?? throw new InvalidOperationException( $"MXAccess COM object of type '{mxAccessComObject.GetType().FullName}' does not implement " + $"{nameof(ILMXProxyServer5)} or {nameof(IMxAccessServer)}."); } }