@@ -21,6 +21,14 @@ namespace OnTopic.Attributes {
2121 /// </remarks>
2222 public class AttributeCollection : TrackedRecordCollection < AttributeRecord , string , AttributeSetterAttribute > {
2323
24+ /*==========================================================================================================================
25+ | PRIVATE VARIABLES
26+ \-------------------------------------------------------------------------------------------------------------------------*/
27+ private static readonly List < string > _excludedAttributes = new ( ) {
28+ nameof ( Topic . Title ) ,
29+ nameof ( Topic . LastModified )
30+ } ;
31+
2432 /*==========================================================================================================================
2533 | CONSTRUCTOR
2634 \-------------------------------------------------------------------------------------------------------------------------*/
@@ -52,7 +60,6 @@ internal AttributeCollection(Topic parentTopic) : base(parentTopic) {
5260 /*==========================================================================================================================
5361 | METHOD: IS DIRTY
5462 \-------------------------------------------------------------------------------------------------------------------------*/
55-
5663 /// <summary>
5764 /// Determine if <i>any</i> attributes in the <see cref="AttributeCollection"/> are dirty.
5865 /// </summary>
@@ -133,5 +140,36 @@ public void SetValue(
133140 }
134141 }
135142
143+ /*==========================================================================================================================
144+ | METHOD: AS ATTRIBUTE DICTIONARY
145+ \-------------------------------------------------------------------------------------------------------------------------*/
146+ /// <summary>
147+ /// Gets an <see cref="AttributeDictionary"/> based on the <see cref="Topic.Attributes"/> of the current <see cref="
148+ /// AttributeCollection"/>. Optionall includes attributes from any <see cref="Topic.BaseTopic"/>s that the <see cref="
149+ /// TrackedRecordCollection{TItem, TValue, TAttribute}.AssociatedTopic"/> derives from.
150+ /// </summary>
151+ /// <remarks>
152+ /// The <see cref="AsAttributeDictionary(Boolean)"/> method will exclude attributes which correspond to properties on
153+ /// <see cref="Topic"/> which contain specialized getter logic, such as <see cref="Topic.Title"/> and <see cref="Topic.
154+ /// LastModified"/>.
155+ /// </remarks>
156+ /// <param name="inheritFromBase">
157+ /// Determines if attributes from the <see cref="Topic.BaseTopic"/> should be included. Defaults to <c>false</c>.
158+ /// </param>
159+ /// <returns>A new <see cref="AttributeDictionary"/> containing attributes</returns>
160+ public AttributeDictionary AsAttributeDictionary ( bool inheritFromBase = false ) {
161+ var sourceAttributes = ( AttributeCollection ? ) this ;
162+ var attributes = new AttributeDictionary ( ) ;
163+ while ( sourceAttributes is not null ) {
164+ foreach ( var attribute in sourceAttributes ) {
165+ if ( ! _excludedAttributes . Contains ( attribute . Key ) && ! attributes . ContainsKey ( attribute . Key ) ) {
166+ attributes . Add ( attribute . Key , attribute . Value ) ;
167+ }
168+ }
169+ sourceAttributes = inheritFromBase ? sourceAttributes . AssociatedTopic . BaseTopic ? . Attributes : null ;
170+ }
171+ return attributes ;
172+ }
173+
136174 } //Class
137175} //Namespace
0 commit comments