2 // System.ComponentModel.Design.Serialization.MemberRelationshipService
5 // Ivan N. Zlatev (contact@i-nZ.net)
7 // (C) 2007 Ivan N. Zlatev
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System.ComponentModel;
34 using System.Collections;
36 namespace System.ComponentModel.Design.Serialization
38 public abstract class MemberRelationshipService
41 // MSDN: The default implementation stores relationships in a dictionary using weak references
42 // so the relationship table does not keep objects alive.
44 private class MemberRelationshipWeakEntry
47 private WeakReference _ownerWeakRef;
48 private MemberDescriptor _member;
50 public MemberRelationshipWeakEntry (MemberRelationship relation)
52 _ownerWeakRef = new WeakReference (relation.Owner);
53 _member = relation.Member;
58 if (_ownerWeakRef.IsAlive)
59 return _ownerWeakRef.Target;
64 public MemberDescriptor Member {
65 get { return _member; }
68 public static bool operator == (MemberRelationshipWeakEntry left, MemberRelationshipWeakEntry right)
70 if (left.Owner == right.Owner && left.Member == right.Member)
76 public static bool operator != (MemberRelationshipWeakEntry left, MemberRelationshipWeakEntry right)
78 return !(left == right);
81 public override int GetHashCode ()
83 if (this.Owner != null && _member != null)
84 return _member.GetHashCode () ^ _ownerWeakRef.Target.GetHashCode ();
85 return base.GetHashCode ();
88 public override bool Equals (object o)
90 if (o is MemberRelationshipWeakEntry) {
91 return ((MemberRelationshipWeakEntry) o) == this;
97 private Hashtable _relations;
99 protected MemberRelationshipService ()
101 _relations = new Hashtable ();
104 public abstract bool SupportsRelationship (MemberRelationship source, MemberRelationship relationship);
106 protected virtual MemberRelationship GetRelationship (MemberRelationship source)
109 throw new ArgumentNullException ("source");
111 MemberRelationshipWeakEntry entry = _relations[new MemberRelationshipWeakEntry (source)] as MemberRelationshipWeakEntry;
113 return new MemberRelationship (entry.Owner, entry.Member);
114 return MemberRelationship.Empty;
117 protected virtual void SetRelationship (MemberRelationship source, MemberRelationship relationship)
120 throw new ArgumentNullException ("source");
122 if (!relationship.IsEmpty && !this.SupportsRelationship (source, relationship))
123 throw new ArgumentException ("Relationship not supported.");
125 _relations[new MemberRelationshipWeakEntry (source)] = new MemberRelationshipWeakEntry (relationship);
128 public MemberRelationship this [object owner, MemberDescriptor member] {
129 get { return GetRelationship (new MemberRelationship (owner, member)); }
130 set { SetRelationship (new MemberRelationship (owner, member), value); }
133 public MemberRelationship this [MemberRelationship source] {
134 get { return GetRelationship (source); }
135 set { SetRelationship (source, value); }