Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>options:</p> <ol> <li>implement a membership test, e.g. check bar-is-member-of-foo before adding</li> <li>move the many-to-many relationship to its own class</li> </ol> <p>the latter is preferred, i think - it's more relationally sound</p> <p>of course, with a foo-bar example we really don't know what the goal is, so your mileage may vary</p> <p>EDIT: given the code in the original question, #1 will not work because the infinite recursion happens before anything is ever added to any list.</p> <p>There are several problems with this approach/question, probably because it has been abstracted to the point of near silliness - good for illustrating the coding problem, no so good for explaining the original intent/goal:</p> <ol> <li>the wrapper classes don't actually wrap anything or add any useful behavior; this makes it difficult to see why they're needed</li> <li>with the given structure, you cannot initialize the lists in the constructor <em>at all</em> because each wrapper list immediately creates a new instance of the other wrapper list</li> <li>even if you separate initialization from construction, you still have a cyclic dependency with hidden membership (i.e. the wrappers reference each other but hide the foo/bar elements from a contains check; which doesn't really matter because the code never gets to add anything to any list anyway!)</li> <li>a direct relational approach would work, but requires searching mechanisms and assumes that wrappers would be created as-needed instead of in advance, e.g. an array with search functions or a pair of dictionaries (e.g. Dictionary>, Dictionary>) would work for the mapping but might not fit your object model</li> </ol> <h1>Conclusion</h1> <p>I don't think the structure <em>as described</em> will work. Not with DI, not with a factory, not at all - because the wrappers reference each other while hiding the sublists.</p> <p>This structure hints at unstated incorrect assumptions, but with no context we can't ferret out what they might be.</p> <p>Please restate the problem in the original context with real-world objects and desired goal/intent. </p> <p>Or at least state what structure you think your sample code <em>should</em> produce. ;-)</p> <h1>Addendum</h1> <p>Thanks for the clarification, this makes the situation more comprehensible.</p> <p>I have not worked with WPF databinding - but I have skimmed <a href="http://msdn.microsoft.com/en-us/magazine/dd458800.aspx" rel="nofollow noreferrer">this MSDN article</a> - so the following may or may not be helpful and/or correct:</p> <ul> <li>I think the categories and recipes collections in the view-model classes are redundant <ul> <li>you already have the M:M information in the underlying category object, so why duplicate it in the view-model</li> <li>it looks like your collection-changed handlers will also cause infinite recursion</li> <li>the collection-changed handlers do not appear to update the underlying M:M information for the wrapped recipe/category</li> </ul></li> <li>I think the purpose of the view-model is to expose the underlying model data, not to indivudally wrap each of its components. <ul> <li>This seems redundant and a violation of encapsulation</li> <li>It is also the source of your infinite-recursion problem</li> <li>Naively, I would expect the ObservableCollection properties to merely return the underlying model's collections...</li> </ul></li> </ul> <p>The structure you have is an "inverted index" representation of a many-to-many relationship, which is quite common for optimized lookups and dependency management. It reduces to a pair of one-to-many relationships. Look at the GamesViewModel example in the MSDN article - note that the Games property is just </p> <pre><code>ObservableCollection&lt;Game&gt; </code></pre> <p>and not</p> <pre><code>ObservableCollection&lt;GameWrapper&gt; </code></pre>
 

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