a521c72efe157c25e34b4a94f68dd1d2d2339126
[platform/upstream/dotnet/runtime.git] /
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3
4 using System;
5 using System.Collections.Generic;
6 using System.ComponentModel.Composition.Primitives;
7 using System.Linq;
8 using System.Reflection;
9 using System.UnitTesting;
10 using Microsoft.Internal;
11 using Xunit;
12
13 namespace System.ComponentModel.Composition.ReflectionModel
14 {
15     public class ReflectionModelServicesTests
16     {
17         [Fact]
18         public void CreatePartDefinition()
19         {
20             Type expectedType = typeof(TestPart);
21             Lazy<Type> expectedLazyType = expectedType.AsLazy();
22             IDictionary<string, object> expectedMetadata = new Dictionary<string, object>();
23             expectedMetadata["Key1"] = 1;
24             expectedMetadata["Key2"] = "Value2";
25
26             IEnumerable<ImportDefinition> expectedImports = CreateImports(expectedType);
27             IEnumerable<ExportDefinition> expectedExports = CreateExports(expectedType);
28
29             ICompositionElement expectedOrigin = new MockOrigin();
30
31             ComposablePartDefinition partDefinition = ReflectionModelServices.CreatePartDefinition(expectedLazyType, false,
32                 new Lazy<IEnumerable<ImportDefinition>>(() => expectedImports),
33                 new Lazy<IEnumerable<ExportDefinition>>(() => expectedExports),
34                 expectedMetadata.AsLazy(), expectedOrigin);
35             Assert.NotNull(partDefinition);
36
37             ReflectionComposablePartDefinition definition = partDefinition as ReflectionComposablePartDefinition;
38             Assert.NotNull(definition);
39
40             Assert.Same(expectedType, definition.GetPartType());
41             Assert.True(definition.Metadata.Keys.SequenceEqual(expectedMetadata.Keys));
42             Assert.True(definition.Metadata.Values.SequenceEqual(expectedMetadata.Values));
43             Assert.True(definition.ExportDefinitions.SequenceEqual(expectedExports.Cast<ExportDefinition>()));
44             Assert.True(definition.ImportDefinitions.SequenceEqual(expectedImports.Cast<ImportDefinition>()));
45             Assert.Same(expectedOrigin, ((ICompositionElement)definition).Origin);
46             Assert.NotNull(((ICompositionElement)definition).DisplayName);
47             Assert.False(definition.IsDisposalRequired);
48         }
49
50         [Fact]
51         public void CreatePartDefinition_Disposable()
52         {
53             Type expectedType = typeof(TestPart);
54             Lazy<Type> expectedLazyType = expectedType.AsLazy();
55             IDictionary<string, object> expectedMetadata = new Dictionary<string, object>();
56             expectedMetadata["Key1"] = 1;
57             expectedMetadata["Key2"] = "Value2";
58
59             IEnumerable<ImportDefinition> expectedImports = CreateImports(expectedType);
60             IEnumerable<ExportDefinition> expectedExports = CreateExports(expectedType);
61
62             ICompositionElement expectedOrigin = new MockOrigin();
63
64             ComposablePartDefinition partDefinition = ReflectionModelServices.CreatePartDefinition(expectedLazyType, true,
65                 new Lazy<IEnumerable<ImportDefinition>>(() => expectedImports),
66                 new Lazy<IEnumerable<ExportDefinition>>(() => expectedExports),
67                 expectedMetadata.AsLazy(), expectedOrigin);
68             Assert.NotNull(partDefinition);
69
70             ReflectionComposablePartDefinition definition = partDefinition as ReflectionComposablePartDefinition;
71             Assert.NotNull(definition);
72
73             Assert.Same(expectedType, definition.GetPartType());
74             Assert.True(definition.Metadata.Keys.SequenceEqual(expectedMetadata.Keys));
75             Assert.True(definition.Metadata.Values.SequenceEqual(expectedMetadata.Values));
76             Assert.True(definition.ExportDefinitions.SequenceEqual(expectedExports.Cast<ExportDefinition>()));
77             Assert.True(definition.ImportDefinitions.SequenceEqual(expectedImports.Cast<ImportDefinition>()));
78             Assert.Same(expectedOrigin, ((ICompositionElement)definition).Origin);
79             Assert.NotNull(((ICompositionElement)definition).DisplayName);
80             Assert.True(definition.IsDisposalRequired);
81         }
82
83         [Fact]
84         public void CreatePartDefinition_NullMetadataAllowed()
85         {
86             Type expectedType = typeof(TestPart);
87             Lazy<Type> expectedLazyType = expectedType.AsLazy();
88
89             IEnumerable<ImportDefinition> expectedImports = CreateImports(expectedType);
90             IEnumerable<ExportDefinition> expectedExports = CreateExports(expectedType);
91
92             ICompositionElement expectedOrigin = new MockOrigin();
93
94             ComposablePartDefinition partDefinition = ReflectionModelServices.CreatePartDefinition(expectedLazyType, false,
95                 new Lazy<IEnumerable<ImportDefinition>>(() => expectedImports),
96                 new Lazy<IEnumerable<ExportDefinition>>(() => expectedExports),
97                 null, expectedOrigin);
98             Assert.NotNull(partDefinition);
99
100             ReflectionComposablePartDefinition definition = partDefinition as ReflectionComposablePartDefinition;
101             Assert.NotNull(definition);
102             Assert.NotNull(definition.Metadata);
103             Assert.Equal(0, definition.Metadata.Count);
104         }
105
106         [Fact]
107         public void CreatePartDefinition_EvaluatedNullMetadataAllowed()
108         {
109             Type expectedType = typeof(TestPart);
110             Lazy<Type> expectedLazyType = expectedType.AsLazy();
111             IDictionary<string, object> expectedMetadata = null;
112
113             IEnumerable<ImportDefinition> expectedImports = CreateImports(expectedType);
114             IEnumerable<ExportDefinition> expectedExports = CreateExports(expectedType);
115
116             ICompositionElement expectedOrigin = new MockOrigin();
117
118             ComposablePartDefinition partDefinition = ReflectionModelServices.CreatePartDefinition(expectedLazyType, false,
119                 new Lazy<IEnumerable<ImportDefinition>>(() => expectedImports),
120                 new Lazy<IEnumerable<ExportDefinition>>(() => expectedExports),
121                 expectedMetadata.AsLazy(), expectedOrigin);
122             Assert.NotNull(partDefinition);
123
124             ReflectionComposablePartDefinition definition = partDefinition as ReflectionComposablePartDefinition;
125             Assert.NotNull(definition);
126             Assert.NotNull(definition.Metadata);
127             Assert.Equal(0, definition.Metadata.Count);
128         }
129
130         [Fact]
131         public void CreatePartDefinition_NullExportsAllowed()
132         {
133             Type expectedType = typeof(TestPart);
134             Lazy<Type> expectedLazyType = expectedType.AsLazy();
135
136             IEnumerable<ImportDefinition> expectedImports = CreateImports(expectedType);
137             IEnumerable<ExportDefinition> expectedExports = CreateExports(expectedType);
138             IDictionary<string, object> expectedMetadata = new Dictionary<string, object>();
139
140             ICompositionElement expectedOrigin = new MockOrigin();
141
142             ComposablePartDefinition partDefinition = ReflectionModelServices.CreatePartDefinition(expectedLazyType, false,
143                 new Lazy<IEnumerable<ImportDefinition>>(() => expectedImports),
144                 null,
145                 expectedMetadata.AsLazy(), expectedOrigin);
146             Assert.NotNull(partDefinition);
147
148             ReflectionComposablePartDefinition definition = partDefinition as ReflectionComposablePartDefinition;
149             Assert.NotNull(definition);
150             Assert.NotNull(definition.ExportDefinitions);
151             Assert.Equal(0, definition.ExportDefinitions.Count());
152         }
153
154         [Fact]
155         public void CreatePartDefinition_EvaluatedNullExportsAllowed()
156         {
157             Type expectedType = typeof(TestPart);
158             Lazy<Type> expectedLazyType = expectedType.AsLazy();
159
160             IEnumerable<ImportDefinition> expectedImports = CreateImports(expectedType);
161             IEnumerable<ExportDefinition> expectedExports = CreateExports(expectedType);
162             IDictionary<string, object> expectedMetadata = new Dictionary<string, object>();
163
164             ICompositionElement expectedOrigin = new MockOrigin();
165
166             ComposablePartDefinition partDefinition = ReflectionModelServices.CreatePartDefinition(expectedLazyType, false,
167                 new Lazy<IEnumerable<ImportDefinition>>(() => expectedImports),
168                 new Lazy<IEnumerable<ExportDefinition>>(() => null),
169                 expectedMetadata.AsLazy(), expectedOrigin);
170             Assert.NotNull(partDefinition);
171
172             ReflectionComposablePartDefinition definition = partDefinition as ReflectionComposablePartDefinition;
173             Assert.NotNull(definition);
174             Assert.NotNull(definition.ExportDefinitions);
175             Assert.Equal(0, definition.ExportDefinitions.Count());
176         }
177
178         [Fact]
179         public void CreatePartDefinition_ExportsMustBeOfRightType()
180         {
181             Type expectedType = typeof(TestPart);
182             Lazy<Type> expectedLazyType = expectedType.AsLazy();
183
184             IEnumerable<ImportDefinition> expectedImports = CreateImports(expectedType);
185             IEnumerable<ExportDefinition> expectedExports = CreateExports(expectedType);
186             IDictionary<string, object> expectedMetadata = new Dictionary<string, object>();
187
188             ICompositionElement expectedOrigin = new MockOrigin();
189
190             ComposablePartDefinition partDefinition = ReflectionModelServices.CreatePartDefinition(expectedLazyType, false,
191                 new Lazy<IEnumerable<ImportDefinition>>(() => expectedImports),
192                 new Lazy<IEnumerable<ExportDefinition>>(() => CreateInvalidExports()),
193                 expectedMetadata.AsLazy(), expectedOrigin);
194             Assert.NotNull(partDefinition);
195
196             ReflectionComposablePartDefinition definition = partDefinition as ReflectionComposablePartDefinition;
197             Assert.NotNull(definition);
198
199             ExceptionAssert.Throws<InvalidOperationException>(() =>
200             {
201                 definition.ExportDefinitions.Count();
202             });
203         }
204
205         [Fact]
206         public void CreatePartDefinition_NullImportsAllowed()
207         {
208             Type expectedType = typeof(TestPart);
209             Lazy<Type> expectedLazyType = expectedType.AsLazy();
210
211             IEnumerable<ImportDefinition> expectedImports = CreateImports(expectedType);
212             IEnumerable<ExportDefinition> expectedExports = CreateExports(expectedType);
213             IDictionary<string, object> expectedMetadata = new Dictionary<string, object>();
214
215             ICompositionElement expectedOrigin = new MockOrigin();
216
217             ComposablePartDefinition partDefinition = ReflectionModelServices.CreatePartDefinition(expectedLazyType, false,
218                 null,
219                 new Lazy<IEnumerable<ExportDefinition>>(() => expectedExports),
220                 expectedMetadata.AsLazy(), expectedOrigin);
221             Assert.NotNull(partDefinition);
222
223             ReflectionComposablePartDefinition definition = partDefinition as ReflectionComposablePartDefinition;
224             Assert.NotNull(definition);
225             Assert.NotNull(definition.ImportDefinitions);
226             Assert.Equal(0, definition.ImportDefinitions.Count());
227         }
228
229         [Fact]
230         public void CreatePartDefinition_EvaluatedNullImportsAllowed()
231         {
232             Type expectedType = typeof(TestPart);
233             Lazy<Type> expectedLazyType = expectedType.AsLazy();
234
235             IEnumerable<ImportDefinition> expectedImports = CreateImports(expectedType);
236             IEnumerable<ExportDefinition> expectedExports = CreateExports(expectedType);
237             IDictionary<string, object> expectedMetadata = new Dictionary<string, object>();
238
239             ICompositionElement expectedOrigin = new MockOrigin();
240
241             ComposablePartDefinition partDefinition = ReflectionModelServices.CreatePartDefinition(expectedLazyType, false,
242                 new Lazy<IEnumerable<ImportDefinition>>(() => null),
243                 new Lazy<IEnumerable<ExportDefinition>>(() => expectedExports),
244                 expectedMetadata.AsLazy(), expectedOrigin);
245             Assert.NotNull(partDefinition);
246
247             ReflectionComposablePartDefinition definition = partDefinition as ReflectionComposablePartDefinition;
248             Assert.NotNull(definition);
249             Assert.NotNull(definition.ImportDefinitions);
250             Assert.Equal(0, definition.ImportDefinitions.Count());
251         }
252
253         [Fact]
254         public void CreatePartDefinition_ImportsMustBeOfRightType()
255         {
256             Type expectedType = typeof(TestPart);
257             Lazy<Type> expectedLazyType = expectedType.AsLazy();
258
259             IEnumerable<ImportDefinition> expectedImports = CreateImports(expectedType);
260             IEnumerable<ExportDefinition> expectedExports = CreateExports(expectedType);
261             IDictionary<string, object> expectedMetadata = new Dictionary<string, object>();
262
263             ICompositionElement expectedOrigin = new MockOrigin();
264
265             ComposablePartDefinition partDefinition = ReflectionModelServices.CreatePartDefinition(expectedLazyType, false,
266                 new Lazy<IEnumerable<ImportDefinition>>(() => CreateInvalidImports()),
267                 new Lazy<IEnumerable<ExportDefinition>>(() => expectedExports),
268                 expectedMetadata.AsLazy(), expectedOrigin);
269             Assert.NotNull(partDefinition);
270
271             ReflectionComposablePartDefinition definition = partDefinition as ReflectionComposablePartDefinition;
272             Assert.NotNull(definition);
273             ExceptionAssert.Throws<InvalidOperationException>(() =>
274             {
275                 definition.ImportDefinitions.Count();
276             });
277
278         }
279
280         [Fact]
281         public void CreatePartDefinition_NullTypeNotAllowed()
282         {
283             Type expectedType = typeof(TestPart);
284             Lazy<Type> expectedLazyType = expectedType.AsLazy();
285             IDictionary<string, object> expectedMetadata = new Dictionary<string, object>();
286             expectedMetadata["Key1"] = 1;
287             expectedMetadata["Key2"] = "Value2";
288
289             IEnumerable<ImportDefinition> expectedImports = CreateImports(expectedType);
290             IEnumerable<ExportDefinition> expectedExports = CreateExports(expectedType);
291
292             ICompositionElement expectedOrigin = new MockOrigin();
293
294             Assert.Throws<ArgumentNullException>("partType", () =>
295             {
296                 ComposablePartDefinition partDefinition = ReflectionModelServices.CreatePartDefinition(null, false,
297                     new Lazy<IEnumerable<ImportDefinition>>(() => expectedImports),
298                     new Lazy<IEnumerable<ExportDefinition>>(() => expectedExports),
299                     expectedMetadata.AsLazy(), expectedOrigin);
300             });
301         }
302
303         [Fact]
304         public void CreatePartDefinition_NullEvaluatedTypeNotAllowed()
305         {
306             Type expectedType = typeof(TestPart);
307             Lazy<Type> expectedLazyType = expectedType.AsLazy();
308
309             IDictionary<string, object> expectedMetadata = new Dictionary<string, object>();
310             expectedMetadata["Key1"] = 1;
311             expectedMetadata["Key2"] = "Value2";
312
313             IEnumerable<ImportDefinition> expectedImports = CreateImports(expectedType);
314             IEnumerable<ExportDefinition> expectedExports = CreateExports(expectedType);
315
316             ICompositionElement expectedOrigin = new MockOrigin();
317
318             ComposablePartDefinition partDefinition = ReflectionModelServices.CreatePartDefinition(new Lazy<Type>(() => null), false,
319                 new Lazy<IEnumerable<ImportDefinition>>(() => expectedImports),
320                 new Lazy<IEnumerable<ExportDefinition>>(() => expectedExports),
321                 expectedMetadata.AsLazy(), expectedOrigin);
322
323             ReflectionComposablePartDefinition definition = partDefinition as ReflectionComposablePartDefinition;
324             Assert.NotNull(definition);
325
326             ExceptionAssert.Throws<InvalidOperationException>(() =>
327             {
328                 definition.GetPartType();
329             });
330         }
331
332         [Fact]
333         public void GetPartType()
334         {
335             Type expectedType = typeof(TestPart);
336             Lazy<Type> expectedLazyType = expectedType.AsLazy();
337             IDictionary<string, object> expectedMetadata = new Dictionary<string, object>();
338             expectedMetadata["Key1"] = 1;
339             expectedMetadata["Key2"] = "Value2";
340
341             IEnumerable<ImportDefinition> expectedImports = CreateImports(expectedType);
342             IEnumerable<ExportDefinition> expectedExports = CreateExports(expectedType);
343
344             ICompositionElement expectedOrigin = new MockOrigin();
345
346             ComposablePartDefinition partDefinition = ReflectionModelServices.CreatePartDefinition(expectedLazyType, false,
347                 new Lazy<IEnumerable<ImportDefinition>>(() => expectedImports),
348                 new Lazy<IEnumerable<ExportDefinition>>(() => expectedExports),
349                 expectedMetadata.AsLazy(), expectedOrigin);
350             Assert.NotNull(partDefinition);
351
352             Lazy<Type> lazyPartType = ReflectionModelServices.GetPartType(partDefinition);
353             Assert.Equal(expectedLazyType, lazyPartType);
354         }
355
356         [Fact]
357         public void GetPartType_NullAsPart_ShouldThrowArgumentNull()
358         {
359             Assert.Throws<ArgumentNullException>("partDefinition", () =>
360             {
361                 ReflectionModelServices.GetPartType(null);
362             });
363         }
364
365         [Fact]
366         public void GetPartType_InvalidPart_ShouldThrowArgument()
367         {
368             Assert.Throws<ArgumentException>("partDefinition", () =>
369             {
370                 ReflectionModelServices.GetPartType(new InvalidPartDefinition());
371             });
372         }
373
374         [Fact]
375         public void IsDisposalRequired_ForNonDisposable()
376         {
377             Type expectedType = typeof(TestPart);
378             Lazy<Type> expectedLazyType = expectedType.AsLazy();
379             IDictionary<string, object> expectedMetadata = new Dictionary<string, object>();
380             expectedMetadata["Key1"] = 1;
381             expectedMetadata["Key2"] = "Value2";
382
383             IEnumerable<ImportDefinition> expectedImports = CreateImports(expectedType);
384             IEnumerable<ExportDefinition> expectedExports = CreateExports(expectedType);
385
386             ICompositionElement expectedOrigin = new MockOrigin();
387
388             ComposablePartDefinition partDefinition = ReflectionModelServices.CreatePartDefinition(expectedLazyType, false,
389                 new Lazy<IEnumerable<ImportDefinition>>(() => expectedImports),
390                 new Lazy<IEnumerable<ExportDefinition>>(() => expectedExports),
391                 expectedMetadata.AsLazy(), expectedOrigin);
392             Assert.NotNull(partDefinition);
393
394             bool isDisposalRequired = ReflectionModelServices.IsDisposalRequired(partDefinition);
395             Assert.False(isDisposalRequired);
396         }
397
398         [Fact]
399         public void IsDisposalRequired_ForDisposable()
400         {
401             Type expectedType = typeof(TestPart);
402             Lazy<Type> expectedLazyType = expectedType.AsLazy();
403             IDictionary<string, object> expectedMetadata = new Dictionary<string, object>();
404             expectedMetadata["Key1"] = 1;
405             expectedMetadata["Key2"] = "Value2";
406
407             IEnumerable<ImportDefinition> expectedImports = CreateImports(expectedType);
408             IEnumerable<ExportDefinition> expectedExports = CreateExports(expectedType);
409
410             ICompositionElement expectedOrigin = new MockOrigin();
411
412             ComposablePartDefinition partDefinition = ReflectionModelServices.CreatePartDefinition(expectedLazyType, true,
413                 new Lazy<IEnumerable<ImportDefinition>>(() => expectedImports),
414                 new Lazy<IEnumerable<ExportDefinition>>(() => expectedExports),
415                 expectedMetadata.AsLazy(), expectedOrigin);
416             Assert.NotNull(partDefinition);
417
418             bool isDisposalRequired = ReflectionModelServices.IsDisposalRequired(partDefinition);
419             Assert.True(isDisposalRequired);
420         }
421
422         [Fact]
423         public void IsDisposalRequired_NullAsPart_ShouldThrowArgumentNull()
424         {
425             Assert.Throws<ArgumentNullException>("partDefinition", () =>
426             {
427                 ReflectionModelServices.IsDisposalRequired(null);
428             });
429         }
430
431         [Fact]
432         public void IsDisposalRequired_InvalidPart_ShouldThrowArgument()
433         {
434             Assert.Throws<ArgumentException>("partDefinition", () =>
435             {
436                 ReflectionModelServices.IsDisposalRequired(new InvalidPartDefinition());
437             });
438         }
439
440         [Fact]
441         public void CreateExportDefinition()
442         {
443             PropertyInfo property = typeof(TestPart).GetProperties().First();
444             LazyMemberInfo expectedLazyMember = new LazyMemberInfo(property);
445
446             IDictionary<string, object> expectedMetadata = new Dictionary<string, object>();
447             expectedMetadata["Key1"] = 1;
448             expectedMetadata["Key2"] = "Value2";
449
450             string expectedContractName = "Foo";
451
452             ICompositionElement expectedOrigin = new MockOrigin();
453
454             ExportDefinition exportDefinition = ReflectionModelServices.CreateExportDefinition(expectedLazyMember, expectedContractName, expectedMetadata.AsLazy(), expectedOrigin);
455             Assert.NotNull(exportDefinition);
456             ReflectionMemberExportDefinition definition = exportDefinition as ReflectionMemberExportDefinition;
457             Assert.NotNull(definition);
458
459             Assert.Equal(expectedContractName, definition.ContractName);
460             Assert.True(definition.Metadata.Keys.SequenceEqual(expectedMetadata.Keys));
461             Assert.True(definition.Metadata.Values.SequenceEqual(expectedMetadata.Values));
462             Assert.Equal(expectedOrigin, ((ICompositionElement)definition).Origin);
463             Assert.Equal(expectedLazyMember, definition.ExportingLazyMember);
464         }
465
466         [Fact]
467         public void CreateExportDefinition_NullAsContractName_ThrowsNullArgument()
468         {
469             PropertyInfo property = typeof(TestPart).GetProperties().First();
470             LazyMemberInfo expectedLazyMember = new LazyMemberInfo(property);
471
472             IDictionary<string, object> expectedMetadata = new Dictionary<string, object>();
473             expectedMetadata["Key1"] = 1;
474             expectedMetadata["Key2"] = "Value2";
475
476             ICompositionElement expectedOrigin = new MockOrigin();
477
478             Assert.Throws<ArgumentNullException>("contractName", () =>
479             {
480                 ReflectionModelServices.CreateExportDefinition(expectedLazyMember, null, expectedMetadata.AsLazy(), expectedOrigin);
481             });
482         }
483
484         [Fact]
485         public void CreateExportDefinition_NullAsMetadata_Allowed()
486         {
487             PropertyInfo property = typeof(TestPart).GetProperties().First();
488             LazyMemberInfo expectedLazyMember = new LazyMemberInfo(property);
489
490             IDictionary<string, object> expectedMetadata = new Dictionary<string, object>();
491             expectedMetadata["Key1"] = 1;
492             expectedMetadata["Key2"] = "Value2";
493
494             string expectedContractName = "Foo";
495             ICompositionElement expectedOrigin = new MockOrigin();
496
497             ExportDefinition definition = ReflectionModelServices.CreateExportDefinition(expectedLazyMember, expectedContractName, expectedMetadata.AsLazy(), expectedOrigin);
498             Assert.NotNull(definition.Metadata);
499             Assert.Equal(2, definition.Metadata.Count);
500         }
501
502         [Fact]
503         public void CreateExportDefinition_InvalidLazymemberInfo_ShouldThrowArtument()
504         {
505             EventInfo _event = typeof(TestPart).GetEvents().First();
506             LazyMemberInfo expectedLazyMember = new LazyMemberInfo(_event);
507
508             IDictionary<string, object> expectedMetadata = new Dictionary<string, object>();
509             expectedMetadata["Key1"] = 1;
510             expectedMetadata["Key2"] = "Value2";
511
512             string expectedContractName = "Foo";
513
514             ICompositionElement expectedOrigin = new MockOrigin();
515
516             Assert.Throws<ArgumentException>("exportingMember", () =>
517             {
518                 ReflectionModelServices.CreateExportDefinition(expectedLazyMember, expectedContractName, expectedMetadata.AsLazy(), expectedOrigin);
519             });
520         }
521
522         [Fact]
523         public void GetExportingMember()
524         {
525             PropertyInfo property = typeof(TestPart).GetProperties().First();
526             LazyMemberInfo expectedLazyMember = new LazyMemberInfo(property);
527
528             IDictionary<string, object> expectedMetadata = new Dictionary<string, object>();
529             expectedMetadata["Key1"] = 1;
530             expectedMetadata["Key2"] = "Value2";
531
532             string expectedContractName = "Foo";
533
534             ICompositionElement expectedOrigin = new MockOrigin();
535
536             ExportDefinition exportDefinition = ReflectionModelServices.CreateExportDefinition(expectedLazyMember, expectedContractName, expectedMetadata.AsLazy(), expectedOrigin);
537             Assert.NotNull(exportDefinition);
538
539             LazyMemberInfo lazyMember = ReflectionModelServices.GetExportingMember(exportDefinition);
540             Assert.Equal(expectedLazyMember, lazyMember);
541         }
542
543         [Fact]
544         public void GetExportingMember_NullAsExportDefinition_ShouldThrowArhumentNull()
545         {
546             Assert.Throws<ArgumentNullException>("exportDefinition", () =>
547             {
548                 ReflectionModelServices.GetExportingMember(null);
549             });
550         }
551
552         [Fact]
553         public void GetExportingMember_InvalidExportDefinition_ShouldThrowArhumentNull()
554         {
555             Assert.Throws<ArgumentException>("exportDefinition", () =>
556             {
557                 ReflectionModelServices.GetExportingMember(new ExportDefinition("Foo", null));
558             });
559         }
560
561         [Fact]
562         public void CreateImportDefinition_Member()
563         {
564             PropertyInfo property = typeof(TestPart).GetProperties().First();
565             LazyMemberInfo expectedLazyMember = new LazyMemberInfo(property);
566
567             string expectedContractName = "Foo";
568             string expectedRequiredTypeIdentity = "Bar";
569             KeyValuePair<string, Type>[] expectedRequiredMetadata = new KeyValuePair<string, Type>[] { new KeyValuePair<string, Type>("Key1", typeof(string)), new KeyValuePair<string, Type>("Key2", typeof(int)) };
570             ImportCardinality expectedCardinality = ImportCardinality.ExactlyOne;
571             CreationPolicy expectedCreationPolicy = CreationPolicy.NonShared;
572             bool expectedRecomposable = true;
573
574             ICompositionElement expectedOrigin = new MockOrigin();
575
576             ImportDefinition importDefinition = ReflectionModelServices.CreateImportDefinition(
577                 expectedLazyMember,
578                 expectedContractName,
579                 expectedRequiredTypeIdentity,
580                 expectedRequiredMetadata,
581                 expectedCardinality,
582                 expectedRecomposable,
583                 expectedCreationPolicy,
584                 expectedOrigin);
585             Assert.NotNull(importDefinition);
586
587             ReflectionMemberImportDefinition definition = importDefinition as ReflectionMemberImportDefinition;
588             Assert.NotNull(definition);
589
590             Assert.Equal(expectedLazyMember, definition.ImportingLazyMember);
591             Assert.Equal(definition.ContractName, expectedContractName);
592             Assert.Equal(definition.RequiredTypeIdentity, expectedRequiredTypeIdentity);
593             Assert.True(definition.RequiredMetadata.SequenceEqual(expectedRequiredMetadata));
594             Assert.Equal(definition.Cardinality, expectedCardinality);
595             Assert.Equal(definition.RequiredCreationPolicy, expectedCreationPolicy);
596             Assert.Equal(definition.IsRecomposable, expectedRecomposable);
597             Assert.Same(expectedOrigin, ((ICompositionElement)definition).Origin);
598             Assert.False(definition.IsPrerequisite);
599         }
600
601         [Fact]
602         public void CreateImportDefinition_Member_InvalidMember_ShouldThrowArgument()
603         {
604             MethodInfo method = typeof(TestPart).GetMethods().First();
605             LazyMemberInfo expectedLazyMember = new LazyMemberInfo(method);
606
607             string expectedContractName = "Foo";
608             string expectedRequiredTypeIdentity = "Bar";
609             KeyValuePair<string, Type>[] expectedRequiredMetadata = new KeyValuePair<string, Type>[] { new KeyValuePair<string, Type>("Key1", typeof(string)), new KeyValuePair<string, Type>("Key2", typeof(int)) };
610             ImportCardinality expectedCardinality = ImportCardinality.ExactlyOne;
611             CreationPolicy expectedCreationPolicy = CreationPolicy.NonShared;
612             bool expectedRecomposable = true;
613
614             ICompositionElement expectedOrigin = new MockOrigin();
615
616             Assert.Throws<ArgumentException>("importingMember", () =>
617             {
618                 ReflectionModelServices.CreateImportDefinition(
619                 expectedLazyMember,
620                 expectedContractName,
621                 expectedRequiredTypeIdentity,
622                 expectedRequiredMetadata,
623                 expectedCardinality,
624                 expectedRecomposable,
625                 expectedCreationPolicy,
626                 expectedOrigin);
627             });
628         }
629
630         [Fact]
631         public void GetImporingMember()
632         {
633             PropertyInfo property = typeof(TestPart).GetProperties().First();
634             LazyMemberInfo expectedLazyMember = new LazyMemberInfo(property);
635
636             string expectedContractName = "Foo";
637             string expectedRequiredTypeIdentity = "Bar";
638             KeyValuePair<string, Type>[] expectedRequiredMetadata = new KeyValuePair<string, Type>[] { new KeyValuePair<string, Type>("Key1", typeof(string)), new KeyValuePair<string, Type>("Key2", typeof(int)) };
639             ImportCardinality expectedCardinality = ImportCardinality.ExactlyOne;
640             CreationPolicy expectedCreationPolicy = CreationPolicy.NonShared;
641             bool expectedRecomposable = true;
642
643             ICompositionElement expectedOrigin = new MockOrigin();
644
645             ImportDefinition importDefinition = ReflectionModelServices.CreateImportDefinition(
646                 expectedLazyMember,
647                 expectedContractName,
648                 expectedRequiredTypeIdentity,
649                 expectedRequiredMetadata,
650                 expectedCardinality,
651                 expectedRecomposable,
652                 expectedCreationPolicy,
653                 expectedOrigin);
654             Assert.NotNull(importDefinition);
655
656             LazyMemberInfo lazyMember = ReflectionModelServices.GetImportingMember(importDefinition);
657             Assert.Equal(expectedLazyMember, lazyMember);
658         }
659
660         [Fact]
661         public void GetImporingMember_NullAsImport_ShouldThrowArgumentNull()
662         {
663             Assert.Throws<ArgumentNullException>("importDefinition", () =>
664             {
665                 ReflectionModelServices.GetImportingMember(null);
666             });
667         }
668
669         [Fact]
670         public void GetImporingMember_InvalidImport_ShouldThrowArgument()
671         {
672             Assert.Throws<ArgumentException>("importDefinition", () =>
673             {
674                 ReflectionModelServices.GetImportingMember(new ContractBasedImportDefinition("Foo", "Foo", null, ImportCardinality.ZeroOrMore, false, false, CreationPolicy.Any));
675             });
676         }
677
678         [Fact]
679         public void CreateImportDefinition_Parameter()
680         {
681
682             ParameterInfo parameter = typeof(TestPart).GetConstructor(new Type[] { typeof(int) }).GetParameters()[0];
683             Lazy<ParameterInfo> expectedLazyParameter = parameter.AsLazy();
684
685             string expectedContractName = "Foo";
686             string expectedRequiredTypeIdentity = "Bar";
687             KeyValuePair<string, Type>[] expectedRequiredMetadata = new KeyValuePair<string, Type>[] { new KeyValuePair<string, Type>("Key1", typeof(string)), new KeyValuePair<string, Type>("Key2", typeof(int)) };
688             ImportCardinality expectedCardinality = ImportCardinality.ExactlyOne;
689             CreationPolicy expectedCreationPolicy = CreationPolicy.NonShared;
690
691             ICompositionElement expectedOrigin = new MockOrigin();
692
693             ImportDefinition importDefinition = ReflectionModelServices.CreateImportDefinition(
694                 expectedLazyParameter,
695                 expectedContractName,
696                 expectedRequiredTypeIdentity,
697                 expectedRequiredMetadata,
698                 expectedCardinality,
699                 expectedCreationPolicy,
700                 expectedOrigin);
701             Assert.NotNull(importDefinition);
702
703             ReflectionParameterImportDefinition definition = importDefinition as ReflectionParameterImportDefinition;
704             Assert.NotNull(definition);
705
706             Assert.Equal(expectedLazyParameter, definition.ImportingLazyParameter);
707             Assert.Equal(definition.ContractName, expectedContractName);
708             Assert.Equal(definition.RequiredTypeIdentity, expectedRequiredTypeIdentity);
709             Assert.True(definition.RequiredMetadata.SequenceEqual(expectedRequiredMetadata));
710             Assert.Equal(definition.Cardinality, expectedCardinality);
711             Assert.Equal(definition.RequiredCreationPolicy, expectedCreationPolicy);
712             Assert.False(definition.IsRecomposable);
713             Assert.Same(expectedOrigin, ((ICompositionElement)definition).Origin);
714             Assert.True(definition.IsPrerequisite);
715         }
716
717         [Fact]
718         public void CreateImportDefinition_Parameter_NullAsParamater_ShouldThrowArgumentNull()
719         {
720             ParameterInfo parameter = typeof(TestPart).GetConstructor(new Type[] { typeof(int) }).GetParameters()[0];
721             Lazy<ParameterInfo> expectedLazyParameter = parameter.AsLazy();
722
723             string expectedContractName = "Foo";
724             string expectedRequiredTypeIdentity = "Bar";
725             KeyValuePair<string, Type>[] expectedRequiredMetadata = new KeyValuePair<string, Type>[] { new KeyValuePair<string, Type>("Key1", typeof(string)), new KeyValuePair<string, Type>("Key2", typeof(int)) };
726             ImportCardinality expectedCardinality = ImportCardinality.ExactlyOne;
727             CreationPolicy expectedCreationPolicy = CreationPolicy.NonShared;
728
729             ICompositionElement expectedOrigin = new MockOrigin();
730
731             Assert.Throws<ArgumentNullException>("parameter", () =>
732             {
733                 ReflectionModelServices.CreateImportDefinition(
734                                 null,
735                                 expectedContractName,
736                                 expectedRequiredTypeIdentity,
737                                 expectedRequiredMetadata,
738                                 expectedCardinality,
739                                 expectedCreationPolicy,
740                                 expectedOrigin);
741             });
742         }
743
744         [Fact]
745         public void GetImportingParameter()
746         {
747             ParameterInfo parameter = typeof(TestPart).GetConstructor(new Type[] { typeof(int) }).GetParameters()[0];
748             Lazy<ParameterInfo> expectedLazyParameter = parameter.AsLazy();
749
750             string expectedContractName = "Foo";
751             string expectedRequiredTypeIdentity = "Bar";
752             KeyValuePair<string, Type>[] expectedRequiredMetadata = new KeyValuePair<string, Type>[] { new KeyValuePair<string, Type>("Key1", typeof(string)), new KeyValuePair<string, Type>("Key2", typeof(int)) };
753             ImportCardinality expectedCardinality = ImportCardinality.ExactlyOne;
754             CreationPolicy expectedCreationPolicy = CreationPolicy.NonShared;
755
756             ICompositionElement expectedOrigin = new MockOrigin();
757             ImportDefinition importDefinition = ReflectionModelServices.CreateImportDefinition(
758                 expectedLazyParameter,
759                 expectedContractName,
760                 expectedRequiredTypeIdentity,
761                 expectedRequiredMetadata,
762                 expectedCardinality,
763                 expectedCreationPolicy,
764                 expectedOrigin);
765             Assert.NotNull(importDefinition);
766
767             Lazy<ParameterInfo> lazyParameter = ReflectionModelServices.GetImportingParameter(importDefinition);
768             Assert.Equal(expectedLazyParameter, lazyParameter);
769         }
770
771         [Fact]
772         public void GetImportingParameter_NullAsImport_ShouldThrowArgumentNull()
773         {
774             Assert.Throws<ArgumentNullException>("importDefinition", () =>
775             {
776                 ReflectionModelServices.GetImportingParameter(null);
777             });
778         }
779
780         [Fact]
781         public void GetImportingParameter_InvalidImport_ShouldThrowArgument()
782         {
783             Assert.Throws<ArgumentException>("importDefinition", () =>
784             {
785                 ReflectionModelServices.GetImportingParameter(new ContractBasedImportDefinition("Foo", "Foo", null, ImportCardinality.ZeroOrMore, false, false, CreationPolicy.Any));
786             });
787         }
788
789         [Fact]
790         public void IsImportingParameter_OnParameterImport()
791         {
792             ParameterInfo parameter = typeof(TestPart).GetConstructor(new Type[] { typeof(int) }).GetParameters()[0];
793             Lazy<ParameterInfo> expectedLazyParameter = parameter.AsLazy();
794
795             string expectedContractName = "Foo";
796             string expectedRequiredTypeIdentity = "Bar";
797             KeyValuePair<string, Type>[] expectedRequiredMetadata = new KeyValuePair<string, Type>[] { new KeyValuePair<string, Type>("Key1", typeof(string)), new KeyValuePair<string, Type>("Key2", typeof(int)) };
798             ImportCardinality expectedCardinality = ImportCardinality.ExactlyOne;
799             CreationPolicy expectedCreationPolicy = CreationPolicy.NonShared;
800
801             ICompositionElement expectedOrigin = new MockOrigin();
802             ImportDefinition importDefinition = ReflectionModelServices.CreateImportDefinition(
803                 expectedLazyParameter,
804                 expectedContractName,
805                 expectedRequiredTypeIdentity,
806                 expectedRequiredMetadata,
807                 expectedCardinality,
808                 expectedCreationPolicy,
809                 expectedOrigin);
810             Assert.NotNull(importDefinition);
811
812             Assert.True(ReflectionModelServices.IsImportingParameter(importDefinition));
813         }
814
815         [Fact]
816         public void IsImportingParameter_OnMemberImport()
817         {
818             PropertyInfo property = typeof(TestPart).GetProperties().First();
819             LazyMemberInfo expectedLazyMember = new LazyMemberInfo(property);
820
821             string expectedContractName = "Foo";
822             string expectedRequiredTypeIdentity = "Bar";
823             KeyValuePair<string, Type>[] expectedRequiredMetadata = new KeyValuePair<string, Type>[] { new KeyValuePair<string, Type>("Key1", typeof(string)), new KeyValuePair<string, Type>("Key2", typeof(int)) };
824             ImportCardinality expectedCardinality = ImportCardinality.ExactlyOne;
825             CreationPolicy expectedCreationPolicy = CreationPolicy.NonShared;
826             bool expectedRecomposable = true;
827
828             ICompositionElement expectedOrigin = new MockOrigin();
829
830             ImportDefinition importDefinition = ReflectionModelServices.CreateImportDefinition(
831                 expectedLazyMember,
832                 expectedContractName,
833                 expectedRequiredTypeIdentity,
834                 expectedRequiredMetadata,
835                 expectedCardinality,
836                 expectedRecomposable,
837                 expectedCreationPolicy,
838                 expectedOrigin);
839             Assert.NotNull(importDefinition);
840
841             Assert.False(ReflectionModelServices.IsImportingParameter(importDefinition));
842         }
843
844         [Fact]
845         public void IsImportingParameter_NullAsImport_ShouldThrowArgumentNull()
846         {
847             Assert.Throws<ArgumentNullException>("importDefinition", () =>
848             {
849                 ReflectionModelServices.IsImportingParameter(null);
850             });
851         }
852
853         [Fact]
854         public void IsImportingParameter_InvalidImport_ShouldThrowArgument()
855         {
856             Assert.Throws<ArgumentException>("importDefinition", () =>
857             {
858                 ReflectionModelServices.IsImportingParameter(new ContractBasedImportDefinition("Foo", "Foo", null, ImportCardinality.ZeroOrMore, false, false, CreationPolicy.Any));
859             });
860         }
861
862         [Fact]
863         public void IsExportFactoryImportDefinition_NullImport_ShouldThrowArgumentNull()
864         {
865             Assert.Throws<ArgumentNullException>("importDefinition", () =>
866                 ReflectionModelServices.IsExportFactoryImportDefinition(null));
867         }
868
869         [Fact]
870         public void IsExportFactoryImportDefinition_InvalidImport_ShouldReturnFalse()
871         {
872             Assert.False(ReflectionModelServices.IsExportFactoryImportDefinition(CreateInvalidImport()));
873         }
874
875         [Fact]
876         public void IsExportFactoryImportDefinition_NonPartCreatorImport_ShouldReturnFalse()
877         {
878             var import = ReflectionModelServices.CreateImportDefinition(
879                 new LazyMemberInfo(MemberTypes.Field, () => new MemberInfo[] { typeof(ReflectionModelServicesTests) }), // bogus member
880                 "Foo",
881                 "Foo",
882                 Enumerable.Empty<KeyValuePair<string, Type>>(),
883                 ImportCardinality.ZeroOrMore,
884                 false,
885                 CreationPolicy.Any,
886                 null);
887
888             Assert.False(ReflectionModelServices.IsExportFactoryImportDefinition(import));
889         }
890
891         [Fact]
892         public void IsExportFactoryImportDefinition_PartCreatorImport_ShouldReturnTrue()
893         {
894             var import = ReflectionModelServices.CreateImportDefinition(
895                 new LazyMemberInfo(MemberTypes.Field, () => new MemberInfo[] { typeof(ReflectionModelServicesTests) }), // bogus member
896                 "Foo",
897                 "Foo",
898                 Enumerable.Empty<KeyValuePair<string, Type>>(),
899                 ImportCardinality.ZeroOrMore,
900                 false,
901                 CreationPolicy.Any,
902                 MetadataServices.EmptyMetadata,
903                 true, //isPartCreator
904                 null);
905
906             Assert.True(ReflectionModelServices.IsExportFactoryImportDefinition(import));
907         }
908
909         [Fact]
910         public void GetExportFactoryProductImportDefinition_NullImport_ShouldThrowArgumentNull()
911         {
912             Assert.Throws<ArgumentNullException>("importDefinition", () =>
913                 ReflectionModelServices.GetExportFactoryProductImportDefinition(null));
914         }
915
916         [Fact]
917         public void GetExportFactoryProductImportDefinition_InvalidImport_ShouldThrowArgument()
918         {
919             Assert.Throws<ArgumentException>("importDefinition", () =>
920                 ReflectionModelServices.GetExportFactoryProductImportDefinition(CreateInvalidImport()));
921         }
922
923         [Fact]
924         public void GetExportFactoryProductImportDefinition_()
925         {
926
927         }
928
929         [Fact]
930         public void GetExportFactoryProductImportDefinition_PartCreatorImport_()
931         {
932             LazyMemberInfo bogusMember = new LazyMemberInfo(MemberTypes.Field, () => new MemberInfo[] { typeof(ReflectionModelServicesTests) });
933             var import = ReflectionModelServices.CreateImportDefinition(
934                 bogusMember,
935                 "Foo",
936                 "Foo",
937                 Enumerable.Empty<KeyValuePair<string, Type>>(),
938                 ImportCardinality.ZeroOrMore,
939                 false,
940                 CreationPolicy.Any,
941                 null,
942                 true, //isPartCreator
943                 null);
944
945             var productImport = ReflectionModelServices.GetExportFactoryProductImportDefinition(import);
946
947             var import2 = ReflectionModelServices.CreateImportDefinition(
948                 bogusMember,
949                 productImport.ContractName,
950                 productImport.RequiredTypeIdentity,
951                 productImport.RequiredMetadata,
952                 productImport.Cardinality,
953                 productImport.IsRecomposable,
954                 productImport.RequiredCreationPolicy,
955                 productImport.Metadata,
956                 true, //isPartCreator
957                 null);
958
959             Assert.Equal(import.ContractName, import2.ContractName);
960             Assert.Equal(import.Cardinality, import2.Cardinality);
961             Assert.Equal(import.IsRecomposable, import2.IsRecomposable);
962             Assert.Equal(import.RequiredCreationPolicy, import2.RequiredCreationPolicy);
963             Assert.Equal(import.RequiredTypeIdentity, import2.RequiredTypeIdentity);
964             EnumerableAssert.AreEqual(import.RequiredMetadata, import2.RequiredMetadata);
965         }
966
967         private static IEnumerable<ImportDefinition> CreateInvalidImports()
968         {
969             yield return new ContractBasedImportDefinition("Foo", "Foo", null, ImportCardinality.ZeroOrMore, false, false, CreationPolicy.Any);
970         }
971
972         private static ImportDefinition CreateInvalidImport()
973         {
974             return new ContractBasedImportDefinition("Foo", "Foo", null, ImportCardinality.ZeroOrMore, false, false, CreationPolicy.Any);
975         }
976
977         private static IEnumerable<ExportDefinition> CreateInvalidExports()
978         {
979             yield return new ExportDefinition("Foo", null);
980         }
981
982         class InvalidPartDefinition : ComposablePartDefinition
983         {
984             public override ComposablePart CreatePart()
985             {
986                 throw new NotImplementedException();
987             }
988
989             public override IEnumerable<ExportDefinition> ExportDefinitions
990             {
991                 get { throw new NotImplementedException(); }
992             }
993
994             public override IEnumerable<ImportDefinition> ImportDefinitions
995             {
996                 get { throw new NotImplementedException(); }
997             }
998         }
999
1000         private static List<ImportDefinition> CreateImports(Type type)
1001         {
1002             List<ImportDefinition> imports = new List<ImportDefinition>();
1003             foreach (PropertyInfo property in type.GetProperties())
1004             {
1005                 imports.Add(new ReflectionMemberImportDefinition(new LazyMemberInfo(property), "Contract", (string)null, new KeyValuePair<string, Type>[] { new KeyValuePair<string, Type>("Key1", typeof(string)), new KeyValuePair<string, Type>("Key2", typeof(int)) }, ImportCardinality.ZeroOrOne, true, false, CreationPolicy.Any, MetadataServices.EmptyMetadata, new TypeOrigin(type)));
1006             }
1007
1008             return imports;
1009         }
1010
1011         private static List<ExportDefinition> CreateExports(Type type)
1012         {
1013             List<ExportDefinition> exports = new List<ExportDefinition>();
1014             foreach (PropertyInfo property in type.GetProperties())
1015             {
1016                 exports.Add(ReflectionModelServices.CreateExportDefinition(new LazyMemberInfo(property), "Contract", new Lazy<IDictionary<string, object>>(() => null), new TypeOrigin(type)));
1017             }
1018
1019             return exports;
1020         }
1021
1022         public class TestPart
1023         {
1024             public TestPart(int arg1)
1025             {
1026             }
1027
1028             public int field1;
1029             public string field2;
1030             public int Property1 { get; set; }
1031             public string Property2
1032             {
1033                 get { return null; }
1034                 set
1035                 {
1036                     this.Event.Invoke(this, null);
1037                 }
1038             }
1039             public event EventHandler Event;
1040         }
1041
1042         private class TypeOrigin : ICompositionElement
1043         {
1044             private readonly Type _type;
1045             private readonly ICompositionElement _orgin;
1046
1047             public TypeOrigin(Type type)
1048                 : this(type, null)
1049             {
1050             }
1051
1052             public TypeOrigin(Type type, ICompositionElement origin)
1053             {
1054                 this._type = type;
1055                 this._orgin = origin;
1056             }
1057
1058             public string DisplayName
1059             {
1060                 get
1061                 {
1062                     return this._type.GetDisplayName();
1063                 }
1064             }
1065
1066             public ICompositionElement Origin
1067             {
1068                 get
1069                 {
1070                     return this._orgin;
1071                 }
1072             }
1073         }
1074
1075         private class MockOrigin : ICompositionElement
1076         {
1077             public string DisplayName
1078             {
1079                 get { throw new NotImplementedException(); }
1080             }
1081
1082             public ICompositionElement Origin
1083             {
1084                 get { throw new NotImplementedException(); }
1085             }
1086         }
1087
1088     }
1089 }