Fix bugs in sizing TableLayoutPanel (Xamarin bug 18638)
[mono.git] / mcs / class / System.ComponentModel.Composition / src / ComponentModel / System / ComponentModel / Composition / Hosting / CompositionBatch.cs
1 // -----------------------------------------------------------------------\r
2 // Copyright (c) Microsoft Corporation.  All rights reserved.\r
3 // -----------------------------------------------------------------------\r
4 using System;\r
5 using System.Collections.Generic;\r
6 using System.ComponentModel.Composition.Primitives;\r
7 using System.Linq;\r
8 using Microsoft.Internal;\r
9 using System.Collections.ObjectModel;\r
10 using System.Diagnostics.CodeAnalysis;\r
11 \r
12 namespace System.ComponentModel.Composition.Hosting\r
13 {\r
14     public partial class CompositionBatch\r
15     {\r
16         private object _lock = new object();\r
17         private bool _copyNeededForAdd;\r
18         private bool _copyNeededForRemove;\r
19         private List<ComposablePart> _partsToAdd;\r
20         private ReadOnlyCollection<ComposablePart> _readOnlyPartsToAdd;\r
21         private List<ComposablePart> _partsToRemove;\r
22         private ReadOnlyCollection<ComposablePart> _readOnlyPartsToRemove;\r
23 \r
24         /// <summary>\r
25         /// Initializes a new instance of the <see cref="CompositionBatch"/> class.\r
26         /// </summary>\r
27         public CompositionBatch() : \r
28             this(null, null)\r
29         {\r
30         }\r
31 \r
32         /// <summary>\r
33         /// Initializes a new instance of the <see cref="CompositionBatch"/> class.\r
34         /// </summary>\r
35         /// <param name="partsToAdd">The parts to add.</param>\r
36         /// <param name="partsToRemove">The parts to remove.</param>\r
37         public CompositionBatch(IEnumerable<ComposablePart> partsToAdd, IEnumerable<ComposablePart> partsToRemove)\r
38         {\r
39             this._partsToAdd = new List<ComposablePart>();\r
40             if (partsToAdd != null)\r
41             {\r
42                 foreach (var part in partsToAdd)\r
43                 {\r
44                     if (part == null)\r
45                     {\r
46                         throw ExceptionBuilder.CreateContainsNullElement("partsToAdd");\r
47                     }\r
48                     this._partsToAdd.Add(part);\r
49                 }\r
50             }\r
51             this._readOnlyPartsToAdd = this._partsToAdd.AsReadOnly();\r
52 \r
53             this._partsToRemove = new List<ComposablePart>();\r
54             if (partsToRemove != null)\r
55             {\r
56                 foreach (var part in partsToRemove)\r
57                 {\r
58                     if (part == null)\r
59                     {\r
60                         throw ExceptionBuilder.CreateContainsNullElement("partsToRemove");\r
61                     }\r
62                     this._partsToRemove.Add(part);\r
63                 }\r
64             }\r
65             this._readOnlyPartsToRemove = this._partsToRemove.AsReadOnly();\r
66         }\r
67 \r
68         /// <summary>\r
69         /// Returns the collection of parts that will be added.\r
70         /// </summary>\r
71         /// <value>The parts to be added.</value>\r
72         public ReadOnlyCollection<ComposablePart> PartsToAdd\r
73         {\r
74             get\r
75             {\r
76                 lock (this._lock)\r
77                 {\r
78                     this._copyNeededForAdd = true;\r
79                     return this._readOnlyPartsToAdd;\r
80                 }\r
81             }\r
82         }\r
83 \r
84         /// <summary>\r
85         /// Returns the collection of parts that will be removed.\r
86         /// </summary>\r
87         /// <value>The parts to be removed.</value>\r
88         public ReadOnlyCollection<ComposablePart> PartsToRemove\r
89         {\r
90             get\r
91             {\r
92                 lock (this._lock)\r
93                 {\r
94                     this._copyNeededForRemove = true;\r
95                     return this._readOnlyPartsToRemove;\r
96                 }\r
97             }\r
98         }\r
99 \r
100         /// <summary>\r
101         ///     Adds the specified part to the <see cref="CompositionBatch"/>.\r
102         /// </summary>\r
103         /// <param name="part">\r
104         /// The part.\r
105         /// </param>\r
106         /// <exception cref="ArgumentNullException">\r
107         ///     <paramref name="part"/> is <see langword="null"/>.\r
108         /// </exception>\r
109         public void AddPart(ComposablePart part)\r
110         {\r
111             Requires.NotNull(part, "part");\r
112             lock (this._lock)\r
113             {\r
114                 if (this._copyNeededForAdd)\r
115                 {\r
116                     this._partsToAdd = new List<ComposablePart>(this._partsToAdd);\r
117                     this._readOnlyPartsToAdd = this._partsToAdd.AsReadOnly();\r
118                     this._copyNeededForAdd = false;\r
119                 }\r
120                 this._partsToAdd.Add(part);\r
121             }\r
122         }\r
123 \r
124         /// <summary>\r
125         ///     Removes the specified part from the <see cref="CompositionBatch"/>.\r
126         /// </summary>\r
127         /// <param name="part">\r
128         /// The part.\r
129         /// </param>\r
130         /// <exception cref="ArgumentNullException">\r
131         ///     <paramref name="part"/> is <see langword="null"/>.\r
132         /// </exception>\r
133         public void RemovePart(ComposablePart part)\r
134         {\r
135             Requires.NotNull(part, "part");\r
136             lock (this._lock)\r
137             {\r
138                 if (this._copyNeededForRemove)\r
139                 {\r
140                     this._partsToRemove = new List<ComposablePart>(this._partsToRemove);\r
141                     this._readOnlyPartsToRemove = this._partsToRemove.AsReadOnly();\r
142                     this._copyNeededForRemove = false;\r
143                 }\r
144                 this._partsToRemove.Add(part);\r
145             }\r
146         }\r
147 \r
148         /// <summary>\r
149         ///     Adds the specified export to the <see cref="CompositionBatch"/>.\r
150         /// </summary>\r
151         /// <param name="export">\r
152         ///     The <see cref="Export"/> to add to the <see cref="CompositionBatch"/>.\r
153         /// </param>\r
154         /// <returns>\r
155         ///     A <see cref="ComposablePart"/> that can be used remove the <see cref="Export"/>\r
156         ///     from the <see cref="CompositionBatch"/>.\r
157         /// </returns>\r
158         /// <exception cref="ArgumentNullException">\r
159         ///     <paramref name="export"/> is <see langword="null"/>.\r
160         /// </exception>\r
161         /// <remarks>\r
162         /// </remarks>\r
163         public ComposablePart AddExport(Export export)\r
164         {\r
165             Requires.NotNull(export, "export");\r
166 \r
167             ComposablePart part = new SingleExportComposablePart(export);\r
168 \r
169             this.AddPart(part);\r
170 \r
171             return part;\r
172         }\r
173     }\r
174 }\r