1 //----------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 //----------------------------------------------------------------
5 namespace System.Activities.Presentation.Metadata
8 using System.Activities.Presentation.Internal.Metadata;
10 using System.Collections;
11 using System.Collections.Generic;
12 using System.ComponentModel;
13 using System.Reflection;
15 using System.Activities.Presentation;
18 // An attribute table is a read only blob of data. How
19 // do you create one? We will have a class called an
20 // Attribute Builder that can be used to create an attribute
21 // table. Attribute builders have methods you can call to
22 // add metadata. When you�re finished, you can produce an
23 // attribute table from the builder. Builder methods also
24 // support callback delegates so the entire process can be
25 // deferred until needed.
27 public class AttributeTableBuilder
30 private MutableAttributeTable _table = new MutableAttributeTable();
31 private bool _cloneOnUse;
34 // Returns an attribute table we can make changes to
36 private MutableAttributeTable MutableTable
41 MutableAttributeTable clone = new MutableAttributeTable();
42 clone.AddTable(_table);
52 // Adds a callback that will be invoked when metadata for the
53 // given type is needed. The callback can add metadata to
54 // to the attribute table on demand, which is much more efficient
55 // than adding metadata up front.
57 // <param name="type"></param>
58 // <param name="callback"></param>
59 public void AddCallback(Type type, AttributeCallback callback)
63 throw FxTrace.Exception.ArgumentNull("type");
67 throw FxTrace.Exception.ArgumentNull("callback");
69 MutableTable.AddCallback(type, callback);
73 // Adds the contents of the provided attributes to this builder.
74 // Conflicts are resolved with a last-in-wins strategy. When
75 // building a large attribute table it is best to use AddCallback
76 // to defer the work of creating attributes until they are needed.
78 // <param name="type">The type to add class-level attributes to.</param>
79 // <param name="attributes">
80 // The new attributes to add.
82 // <exception cref="ArgumentNullException">if type or attributes is null</exception>
83 public void AddCustomAttributes(Type type, params Attribute[] attributes) {
86 throw FxTrace.Exception.ArgumentNull("type");
88 if (attributes == null)
90 throw FxTrace.Exception.ArgumentNull("attributes");
92 MutableTable.AddCustomAttributes(type, attributes);
96 // Adds the contents of the provided attributes to this builder.
97 // Conflicts are resolved with a last-in-wins strategy. When
98 // building a large attribute table it is best to use AddCallback
99 // to defer the work of creating attributes until they are needed.
101 // <param name="ownerType">
102 // The type the member lives on.
104 // <param name="descriptor">An event or property descriptor to add attributes to.</param>
105 // <param name="attributes">
106 // The new attributes to add.
108 // <exception cref="ArgumentNullException">if descriptor or attributes is null</exception>
109 public void AddCustomAttributes(Type ownerType, MemberDescriptor descriptor, params Attribute[] attributes) {
110 if (ownerType == null)
112 throw FxTrace.Exception.ArgumentNull("ownerType");
114 if (descriptor == null)
116 throw FxTrace.Exception.ArgumentNull("descriptor");
118 if (attributes == null)
120 throw FxTrace.Exception.ArgumentNull("attributes");
122 MutableTable.AddCustomAttributes(ownerType, descriptor, attributes);
126 // Adds the contents of the provided attributes to this builder.
127 // Conflicts are resolved with a last-in-wins strategy. When
128 // building a large attribute table it is best to use AddCallback
129 // to defer the work of creating attributes until they are needed.
131 // <param name="ownerType">
132 // The type the member lives on.
134 // <param name="member">An event or property info to add attributes to.</param>
135 // <param name="attributes">
136 // The new attributes to add.
138 // <exception cref="ArgumentNullException">if member or attributes is null</exception>
139 public void AddCustomAttributes(Type ownerType, MemberInfo member, params Attribute[] attributes) {
140 if (ownerType == null)
142 throw FxTrace.Exception.ArgumentNull("ownerType");
146 throw FxTrace.Exception.ArgumentNull("member");
148 if (attributes == null)
150 throw FxTrace.Exception.ArgumentNull("attributes");
152 MutableTable.AddCustomAttributes(ownerType, member, attributes);
156 // Adds attributes to the member with the given name. The member can be a property
157 // or an event. The member is evaluated on demand when the user queries
158 // attributes on a given property or event.
160 // <param name="ownerType">
161 // The type the member lives on.
163 // <param name="memberName">
164 // The member to add attributes for. Only property and event members are supported;
165 // all others will be ignored.
167 // <param name="attributes">
168 // The new attributes to add.
170 public void AddCustomAttributes(Type ownerType, string memberName, params Attribute[] attributes) {
171 if (ownerType == null)
173 throw FxTrace.Exception.ArgumentNull("ownerType");
175 if (memberName == null)
177 throw FxTrace.Exception.ArgumentNull("memberName");
179 MutableTable.AddCustomAttributes(ownerType, memberName, attributes);
183 // Adds the contents of the provided attributes to this builder.
184 // Conflicts are resolved with a last-in-wins strategy. When
185 // building a large attribute table it is best to use AddCallback
186 // to defer the work of creating attributes until they are needed.
188 // <param name="ownerType">
189 // The type that owns the dependency property.
191 // <param name="dp">A dependency property to add attributes to.</param>
192 // <param name="attributes">
193 // The new attributes to add.
195 // <exception cref="ArgumentNullException">if dp, ownerType or attributes is null</exception>
196 public void AddCustomAttributes(Type ownerType, DependencyProperty dp, params Attribute[] attributes) {
197 if (ownerType == null)
199 throw FxTrace.Exception.ArgumentNull("ownerType");
203 throw FxTrace.Exception.ArgumentNull("dp");
205 if (attributes == null)
207 throw FxTrace.Exception.ArgumentNull("attributes");
209 MutableTable.AddCustomAttributes(ownerType, dp, attributes);
213 // Adds the contents of the provided attribute table to
214 // this builder. Conflicts are resolved with a last-in-wins
217 // <param name="table">An existing attribute table.</param>
218 // <exception cref="ArgumentNullException">if table is null</exception>
219 public void AddTable(AttributeTable table)
223 throw FxTrace.Exception.ArgumentNull("table");
225 MutableTable.AddTable(table.MutableTable);
229 // Creates an attribute table that contains all of the attribute
230 // definitions provided through AddAttribute calls. The table is
231 // a snapshot of the current state of the attribute builder; any
232 // subsequent AddAttribute calls are not included in the table.
234 // If callback methods were used to declare attributes, those methods
235 // will not be evaluated during CreateTable. Instead, the table will
236 // contain those callbacks and will evaluate them as needed.
239 // An attribute table that can be passed to the metadata store.
241 public AttributeTable CreateTable()
244 return new AttributeTable(_table);
248 // This method can be used to verify that the attribute table
249 // that is being built contains valid attribute information.
250 // Some overrides of AddCustomAttributes cannot validate that
251 // values passed to their prameters represent valid members on
252 // classes. Therefore, incorrect information passed to
253 // AddCustomAttributes may go undetected. ValidateTable will
254 // run through the contents of the AttributeTableBuilder and
255 // verify that all custom attribute information matches up with
256 // physical members. Note: calling this method can be very
257 // costly so you should only do it when validation is absolutely
260 // <exception cref="AttributeTableValidationException">if the state of the table is invalid.</exception>
261 public void ValidateTable()
263 MutableTable.ValidateTable();