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.
34 using System
.ComponentModel
;
35 using System
.Collections
;
37 namespace System
.ComponentModel
.Design
.Serialization
39 public abstract class MemberRelationshipService
42 // MSDN: The default implementation stores relationships in a dictionary using weak references
43 // so the relationship table does not keep objects alive.
45 private class MemberRelationshipWeakEntry
48 private WeakReference _ownerWeakRef
;
49 private MemberDescriptor _member
;
51 public MemberRelationshipWeakEntry (MemberRelationship relation
)
53 _ownerWeakRef
= new WeakReference (relation
.Owner
);
54 _member
= relation
.Member
;
59 if (_ownerWeakRef
.IsAlive
)
60 return _ownerWeakRef
.Target
;
65 public MemberDescriptor Member
{
66 get { return _member; }
69 public static bool operator == (MemberRelationshipWeakEntry left
, MemberRelationshipWeakEntry right
)
71 if (left
.Owner
== right
.Owner
&& left
.Member
== right
.Member
)
77 public static bool operator != (MemberRelationshipWeakEntry left
, MemberRelationshipWeakEntry right
)
79 return !(left
== right
);
82 public override int GetHashCode ()
84 if (this.Owner
!= null && _member
!= null)
85 return _member
.GetHashCode () ^ _ownerWeakRef
.Target
.GetHashCode ();
86 return base.GetHashCode ();
89 public override bool Equals (object o
)
91 if (o
is MemberRelationshipWeakEntry
) {
92 return ((MemberRelationshipWeakEntry
) o
) == this;
98 private Hashtable _relations
;
100 protected MemberRelationshipService ()
102 _relations
= new Hashtable ();
105 public abstract bool SupportsRelationship (MemberRelationship source
, MemberRelationship relationship
);
107 protected virtual MemberRelationship
GetRelationship (MemberRelationship source
)
110 throw new ArgumentNullException ("source");
112 MemberRelationshipWeakEntry entry
= _relations
[new MemberRelationshipWeakEntry (source
)] as MemberRelationshipWeakEntry
;
114 return new MemberRelationship (entry
.Owner
, entry
.Member
);
115 return MemberRelationship
.Empty
;
118 protected virtual void SetRelationship (MemberRelationship source
, MemberRelationship relationship
)
121 throw new ArgumentNullException ("source");
123 if (!relationship
.IsEmpty
&& !this.SupportsRelationship (source
, relationship
))
124 throw new ArgumentException ("Relationship not supported.");
126 _relations
[new MemberRelationshipWeakEntry (source
)] = new MemberRelationshipWeakEntry (relationship
);
129 public MemberRelationship
this [object owner
, MemberDescriptor member
] {
130 get { return GetRelationship (new MemberRelationship (owner, member)); }
131 set { SetRelationship (new MemberRelationship (owner, member), value); }
134 public MemberRelationship
this [MemberRelationship source
] {
135 get { return GetRelationship (source); }
136 set { SetRelationship (source, value); }