Note that there are some explanatory texts on larger screens.

plurals
  1. POObjects need to be disposed in a specific order: is this a code smell?
    text
    copied!<p><strong>The context</strong></p> <p>I'm working with a Winforms application (.NET 3.5 SP1) which has the concept of workspaces, which can contain n number of panels. Each panel (derives from <code>Panel</code>) has view:</p> <pre> .-----------------------. |Workspace | |.--------. .--------. | ||Panel1 | |Panel2 | | ||.-----. | |.-----. | | |||View1| | ||View2| | | ||'-----' | |'-----' | | |'--------' '--------' | '-----------------------' </pre> <p>All panels get added to the <code>this.Controls</code> collection of the Workspace class (which derives from an <code>UltraTabPageControl</code>, an Infragistics GUI control). Each view is added to the <code>Controls</code> collection of their parent. So, when <code>Dispose</code> is called on the Workspace, the panels and views automatically get disposed, which is completely expected and desired.</p> <p>We have another concept called a <code>ViewManager</code>. It keeps track of all the <code>View</code> controls in the workspace, and is in charge of maintaining a single "master" view. Whenever a <code>View</code> is created, it registers itself with this manager. This adds the <code>View</code> to a list, and then runs some logic to determine the new "master" view and then calls a <code>Synchronize()</code> method on each View.</p> <p>The current design is that, whenever <code>View.Dispose()</code> is called, it unregisters itself from the <code>ViewManager</code>. This removes the <code>View</code> from the list, and then runs corresponding logic that checks for a new master, out of the remaining views.</p> <p><strong>The twist</strong></p> <p>When we are closing an entire workspace, there is one special <code>Panel</code> type that needs to be closed before other panels. So we have code in our <code>Dispose</code> method that looks like this:</p> <pre><code>protected override void Dispose(bool disposing) { var theSpecialPanel = GetSpecialPanel(); if (theSpecialPanel != null) { theSpecialPanel.Dispose(); } base.Dispose(disposing); } </code></pre> <p>If we take out that code, then other panels may be disposed before <code>theSpecialPanel</code>. This causes the logic that checks for a new master panel to be run, calls <code>Synchronize()</code> on each <code>View</code> including this special panel. This throws an </p> <p>"InvalidComObjectException: COM object that has been separated from its underlying RCW cannot be used."</p> <p><strong>The question</strong></p> <p>Is this design is a code smell? Is it strange to enforce that a specific object gets disposed before others?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload