[mcs] Validate more nameof argument expressions
[mono.git] / mcs / class / System.ComponentModel.Composition / Tests / ComponentModelUnitTest / System / Integration / DelayLoadingTests.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;\r
7 using Microsoft.VisualStudio.TestTools.UnitTesting;\r
8 using System.ComponentModel.Composition.Factories;\r
9 using System.ComponentModel.Composition.UnitTesting;\r
10 using System.UnitTesting;\r
11 using System.ComponentModel.Composition.AttributedModel;\r
12 using System.ComponentModel.Composition.Hosting;\r
13 using System.ComponentModel.Composition.Primitives;\r
14 using System.Linq;\r
15 using System.ComponentModel.Composition.ReflectionModel;\r
16 using Microsoft.Internal;\r
17 \r
18 namespace Tests.Integration\r
19 {\r
20     [TestClass]\r
21     public class DelayLoadingTests\r
22     {\r
23         [TestMethod]\r
24         public void PartTypeLoadedLazily()\r
25         {\r
26             var catalog = new TypeLoadNotifyingCatalog(typeof(ExportingPart));\r
27             var container = new CompositionContainer(catalog);\r
28             catalog.AssertNotLoaded(typeof(ExportingPart));\r
29             Assert.AreEqual(0, catalog.LoadedTypes.Count());\r
30 \r
31             Lazy<IExporter> lazyContract = container.GetExport<IExporter>();\r
32             Assert.IsNotNull(lazyContract);\r
33             catalog.AssertNotLoaded(typeof(ExportingPart));\r
34             Assert.AreEqual(0, catalog.LoadedTypes.Count());\r
35 \r
36             IExporter value = lazyContract.Value;\r
37 \r
38             catalog.AssertLoaded(typeof(ExportingPart));\r
39             Assert.AreEqual(1, catalog.LoadedTypes.Count());\r
40         }\r
41 \r
42         [TestMethod]\r
43         public void PartTypeLoadedLazilyEagerDependeciesLoadEagerly()\r
44         {\r
45             var catalog = new TypeLoadNotifyingCatalog(typeof(ExportingPart), typeof(PartImportingEagerly));\r
46             var container = new CompositionContainer(catalog);\r
47             catalog.AssertNotLoaded(typeof(ExportingPart));\r
48             catalog.AssertNotLoaded(typeof(PartImportingEagerly));\r
49             Assert.AreEqual(0, catalog.LoadedTypes.Count());\r
50 \r
51             Lazy<IImporter> lazyContract = container.GetExport<IImporter>();\r
52             Assert.IsNotNull(lazyContract);\r
53             catalog.AssertNotLoaded(typeof(PartImportingEagerly));\r
54             catalog.AssertNotLoaded(typeof(ExportingPart));\r
55             Assert.AreEqual(0, catalog.LoadedTypes.Count());\r
56 \r
57             IImporter value = lazyContract.Value;\r
58             catalog.AssertLoaded(typeof(PartImportingEagerly));\r
59             catalog.AssertLoaded(typeof(ExportingPart));\r
60             Assert.AreEqual(2, catalog.LoadedTypes.Count());\r
61         }\r
62 \r
63         [TestMethod]\r
64         public void PartTypeLoadedLazilyLazyDependeciesLoadLazily()\r
65         {\r
66             var catalog = new TypeLoadNotifyingCatalog(typeof(ExportingPart), typeof(PartImportingLazily));\r
67             var container = new CompositionContainer(catalog);\r
68             catalog.AssertNotLoaded(typeof(ExportingPart));\r
69             catalog.AssertNotLoaded(typeof(PartImportingLazily));\r
70             Assert.AreEqual(0, catalog.LoadedTypes.Count());\r
71 \r
72             Lazy<IImporter> lazyContract = container.GetExport<IImporter>();\r
73             Assert.IsNotNull(lazyContract);\r
74             catalog.AssertNotLoaded(typeof(PartImportingLazily));\r
75             catalog.AssertNotLoaded(typeof(ExportingPart));\r
76             Assert.AreEqual(0, catalog.LoadedTypes.Count());\r
77 \r
78             IImporter value = lazyContract.Value;\r
79             catalog.AssertLoaded(typeof(PartImportingLazily));\r
80             catalog.AssertNotLoaded(typeof(ExportingPart));\r
81             Assert.AreEqual(1, catalog.LoadedTypes.Count());\r
82         }\r
83 \r
84         [TestMethod]\r
85         public void PartTypeLoadedLazilyEagerCollectionDependeciesLoadEagerly()\r
86         {\r
87             var catalog = new TypeLoadNotifyingCatalog(typeof(ExportingPart), typeof(PartImportingCollectionEagerly));\r
88             var container = new CompositionContainer(catalog);\r
89             catalog.AssertNotLoaded(typeof(ExportingPart));\r
90             catalog.AssertNotLoaded(typeof(PartImportingCollectionEagerly));\r
91             Assert.AreEqual(0, catalog.LoadedTypes.Count());\r
92 \r
93             Lazy<IImporter> lazyContract = container.GetExport<IImporter>();\r
94             Assert.IsNotNull(lazyContract);\r
95             catalog.AssertNotLoaded(typeof(PartImportingCollectionEagerly));\r
96             catalog.AssertNotLoaded(typeof(ExportingPart));\r
97             Assert.AreEqual(0, catalog.LoadedTypes.Count());\r
98 \r
99             IImporter value = lazyContract.Value;\r
100             catalog.AssertLoaded(typeof(PartImportingCollectionEagerly));\r
101             catalog.AssertLoaded(typeof(ExportingPart));\r
102             Assert.AreEqual(2, catalog.LoadedTypes.Count());\r
103         }\r
104 \r
105         [TestMethod]\r
106         public void PartTypeLoadedLazilyLazyCollectionDependeciesLoadLazily()\r
107         {\r
108             var catalog = new TypeLoadNotifyingCatalog(typeof(ExportingPart), typeof(PartImportingCollectionLazily));\r
109             var container = new CompositionContainer(catalog);\r
110             catalog.AssertNotLoaded(typeof(ExportingPart));\r
111             catalog.AssertNotLoaded(typeof(PartImportingCollectionLazily));\r
112             Assert.AreEqual(0, catalog.LoadedTypes.Count());\r
113 \r
114             Lazy<IImporter> lazyContract = container.GetExport<IImporter>();\r
115             Assert.IsNotNull(lazyContract);\r
116             catalog.AssertNotLoaded(typeof(PartImportingCollectionLazily));\r
117             catalog.AssertNotLoaded(typeof(ExportingPart));\r
118             Assert.AreEqual(0, catalog.LoadedTypes.Count());\r
119 \r
120             IImporter value = lazyContract.Value;\r
121             catalog.AssertLoaded(typeof(PartImportingCollectionLazily));\r
122             catalog.AssertNotLoaded(typeof(ExportingPart));\r
123             Assert.AreEqual(1, catalog.LoadedTypes.Count());\r
124         }\r
125 \r
126 \r
127         [TestMethod]\r
128         public void PartTypeLoadedLazilyLazyLoopLoadsLazily()\r
129         {\r
130             var catalog = new TypeLoadNotifyingCatalog(typeof(LazyLoopImporter), typeof(LazyLoopExporter));\r
131             var container = new CompositionContainer(catalog);\r
132             catalog.AssertNotLoaded(typeof(LazyLoopImporter));\r
133             catalog.AssertNotLoaded(typeof(LazyLoopExporter));\r
134             Assert.AreEqual(0, catalog.LoadedTypes.Count());\r
135 \r
136             Lazy<IImporter> lazyContract = container.GetExport<IImporter>();\r
137             Assert.IsNotNull(lazyContract);\r
138             catalog.AssertNotLoaded(typeof(LazyLoopImporter));\r
139             catalog.AssertNotLoaded(typeof(LazyLoopExporter));\r
140             Assert.AreEqual(0, catalog.LoadedTypes.Count());\r
141 \r
142             IImporter value = lazyContract.Value;\r
143             catalog.AssertLoaded(typeof(LazyLoopImporter));\r
144             catalog.AssertNotLoaded(typeof(LazyLoopExporter));\r
145             Assert.AreEqual(1, catalog.LoadedTypes.Count());\r
146         }\r
147 \r
148         public class IExporter\r
149         {\r
150         }\r
151 \r
152         public class IImporter\r
153         {\r
154         }\r
155 \r
156         [Export(typeof(IExporter))]\r
157         public class ExportingPart : IExporter\r
158         {\r
159         }\r
160 \r
161         [Export(typeof(IImporter))]\r
162         public class PartImportingLazily : IImporter\r
163         {\r
164             [Import]\r
165             public Lazy<IExporter> Exporter { get; set; }\r
166         }\r
167 \r
168         [Export(typeof(IImporter))]\r
169         public class PartImportingCollectionLazily : IImporter\r
170         {\r
171             [ImportMany]\r
172             public IEnumerable<Lazy<IExporter>> Exporters { get; set; }\r
173         }\r
174 \r
175         [Export(typeof(IImporter))]\r
176         public class PartImportingEagerly : IImporter\r
177         {\r
178             [Import]\r
179             public IExporter Exporter { get; set; }\r
180         }\r
181 \r
182         [Export(typeof(IImporter))]\r
183         public class PartImportingCollectionEagerly : IImporter\r
184         {\r
185             [ImportMany]\r
186             public IEnumerable<IExporter> Exporters { get; set; }\r
187         }\r
188 \r
189 \r
190         [Export(typeof(IImporter))]\r
191         public class LazyLoopImporter : IImporter\r
192         {\r
193             [Import]\r
194             public Lazy<IExporter> Exporter { get; set; }\r
195         }\r
196 \r
197         [Export(typeof(IExporter))]\r
198         public class LazyLoopExporter : IExporter\r
199         {\r
200             [Import]\r
201             public Lazy<IImporter> Importer { get; set; }\r
202         }\r
203        \r
204 \r
205         private class TypeLoadNotifyingCatalog : ComposablePartCatalog\r
206         {\r
207             ComposablePartDefinition[] _definitions;\r
208             public HashSet<Type> LoadedTypes { get; private set; }\r
209 \r
210             public TypeLoadNotifyingCatalog(params Type[] types)\r
211             {\r
212                 this._definitions = types.Select(type => this.CreatePartDefinition(type)).ToArray();\r
213                 this.LoadedTypes = new HashSet<Type>();\r
214             }\r
215 \r
216             public override IQueryable<ComposablePartDefinition> Parts\r
217             {\r
218                 get { return this._definitions.AsQueryable(); }\r
219             }\r
220 \r
221             private ComposablePartDefinition CreatePartDefinition(Type type)\r
222             {\r
223                 ComposablePartDefinition partDefinition = AttributedModelServices.CreatePartDefinition(type, null);\r
224                 return this.CreateWrapped(partDefinition, type);\r
225             }\r
226 \r
227             private ComposablePartDefinition CreateWrapped(ComposablePartDefinition partDefinition, Type type)\r
228             {\r
229                 IEnumerable<ExportDefinition> exports = partDefinition.ExportDefinitions.Select(e => this.CreateWrapped(e, type)).ToArray();\r
230                 IEnumerable<ImportDefinition> imports = partDefinition.ImportDefinitions.Cast<ContractBasedImportDefinition>().Select(i => this.CreateWrapped(i, type)).ToArray();\r
231 \r
232                 return ReflectionModelServices.CreatePartDefinition(\r
233                     this.CreateWrapped(ReflectionModelServices.GetPartType(partDefinition), type),\r
234                     ReflectionModelServices.IsDisposalRequired(partDefinition),\r
235                     imports.AsLazy(),\r
236                     exports.AsLazy(),\r
237                     partDefinition.Metadata.AsLazy(),\r
238                     null);\r
239             }\r
240 \r
241             private Lazy<T> CreateWrapped<T>(Lazy<T> lazy, Type type)\r
242             {\r
243                 return new Lazy<T>(\r
244                     () => { this.OnTypeLoaded(type); return lazy.Value; });\r
245             }\r
246 \r
247             private LazyMemberInfo CreateWrapped(LazyMemberInfo lazyMember, Type type)\r
248             {\r
249                 return new LazyMemberInfo(\r
250                     lazyMember.MemberType,\r
251                     () => { this.OnTypeLoaded(type); return lazyMember.GetAccessors(); });\r
252             }\r
253 \r
254             private ExportDefinition CreateWrapped(ExportDefinition export, Type type)\r
255             {\r
256                 return ReflectionModelServices.CreateExportDefinition(\r
257                     this.CreateWrapped(ReflectionModelServices.GetExportingMember(export), type),\r
258                     export.ContractName,\r
259                     export.Metadata.AsLazy(),\r
260                     null);\r
261             }\r
262 \r
263             private ImportDefinition CreateWrapped(ContractBasedImportDefinition import, Type type)\r
264             {\r
265                 if (ReflectionModelServices.IsImportingParameter(import))\r
266                 {\r
267                     return ReflectionModelServices.CreateImportDefinition(\r
268                         this.CreateWrapped(ReflectionModelServices.GetImportingParameter(import), type),\r
269                         import.ContractName,\r
270                         import.RequiredTypeIdentity,\r
271                         import.RequiredMetadata,\r
272                         import.Cardinality,\r
273                         import.RequiredCreationPolicy,\r
274                         null);\r
275                 }\r
276                 else\r
277                 {\r
278                     return ReflectionModelServices.CreateImportDefinition(\r
279                         this.CreateWrapped(ReflectionModelServices.GetImportingMember(import), type),\r
280                         import.ContractName,\r
281                         import.RequiredTypeIdentity,\r
282                         import.RequiredMetadata,\r
283                         import.Cardinality,\r
284                         import.IsRecomposable,\r
285                         import.RequiredCreationPolicy,\r
286                         null);\r
287                 }\r
288             }\r
289 \r
290 \r
291 \r
292             private void OnTypeLoaded(Type type)\r
293             {\r
294                 this.LoadedTypes.Add(type);\r
295             }\r
296 \r
297             public void AssertLoaded(Type type)\r
298             {\r
299                 Assert.IsTrue(this.LoadedTypes.Contains(type));\r
300             }\r
301 \r
302             public void AssertNotLoaded(Type type)\r
303             {\r
304                 Assert.IsFalse(this.LoadedTypes.Contains(type));\r
305             }\r
306 \r
307         }\r
308     }\r
309 }\r